Merge "Hiding the AsyncTaskLoader.waitForLoader method" into honeycomb
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 0670c4e..2f96782 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1629,6 +1629,11 @@
/* package */ synchronized void setPrivateBrowsingEnabled(boolean flag) {
if (mPrivateBrowsingEnabled != flag) {
mPrivateBrowsingEnabled = flag;
+
+ // AutoFill is dependant on private browsing being enabled so
+ // reset it to take account of the new value of mPrivateBrowsingEnabled.
+ setAutoFillEnabled(mAutoFillEnabled);
+
postSync();
}
}
@@ -1644,8 +1649,10 @@
* @hide
*/
public synchronized void setAutoFillEnabled(boolean enabled) {
- if (mAutoFillEnabled != enabled) {
- mAutoFillEnabled = enabled;
+ // AutoFill is always disabled in private browsing mode.
+ boolean autoFillEnabled = enabled && !mPrivateBrowsingEnabled;
+ if (mAutoFillEnabled != autoFillEnabled) {
+ mAutoFillEnabled = autoFillEnabled;
postSync();
}
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index eddfffe..78d4cd2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1037,7 +1037,7 @@
String host = proxyProperties.getHost();
int port = proxyProperties.getPort();
if (port != 0)
- host += ": " + port;
+ host += ":" + port;
// TODO: Handle exclusion list
// The plan is to make an AndroidProxyResolver, and handle the blacklist
@@ -6723,43 +6723,60 @@
}
}
- /*
- * Return true if the view (Plugin) is fully visible and maximized inside
- * the WebView.
+ /**
+ * Returns plugin bounds if x/y in content coordinates corresponds to a
+ * plugin. Otherwise a NULL rectangle is returned.
*/
- boolean isPluginFitOnScreen(ViewManager.ChildView view) {
+ Rect getPluginBounds(int x, int y) {
+ if (nativePointInNavCache(x, y, mNavSlop) && nativeCacheHitIsPlugin()) {
+ return nativeCacheHitNodeBounds();
+ } else {
+ return null;
+ }
+ }
+
+ /*
+ * Return true if the rect (e.g. plugin) is fully visible and maximized
+ * inside the WebView.
+ */
+ boolean isRectFitOnScreen(Rect rect) {
+ final int rectWidth = rect.width();
+ final int rectHeight = rect.height();
final int viewWidth = getViewWidth();
final int viewHeight = getViewHeightWithTitle();
- float scale = Math.min((float) viewWidth / view.width, (float) viewHeight / view.height);
+ float scale = Math.min((float) viewWidth / rectWidth, (float) viewHeight / rectHeight);
scale = mZoomManager.computeScaleWithLimits(scale);
return !mZoomManager.willScaleTriggerZoom(scale)
- && contentToViewX(view.x) >= mScrollX
- && contentToViewX(view.x + view.width) <= mScrollX + viewWidth
- && contentToViewY(view.y) >= mScrollY
- && contentToViewY(view.y + view.height) <= mScrollY + viewHeight;
+ && contentToViewX(rect.left) >= mScrollX
+ && contentToViewX(rect.right) <= mScrollX + viewWidth
+ && contentToViewY(rect.top) >= mScrollY
+ && contentToViewY(rect.bottom) <= mScrollY + viewHeight;
}
/*
* Maximize and center the rectangle, specified in the document coordinate
* space, inside the WebView. If the zoom doesn't need to be changed, do an
* animated scroll to center it. If the zoom needs to be changed, find the
- * zoom center and do a smooth zoom transition.
+ * zoom center and do a smooth zoom transition. The rect is in document
+ * coordinates
*/
- void centerFitRect(int docX, int docY, int docWidth, int docHeight) {
- int viewWidth = getViewWidth();
- int viewHeight = getViewHeightWithTitle();
- float scale = Math.min((float) viewWidth / docWidth, (float) viewHeight
- / docHeight);
+ void centerFitRect(Rect rect) {
+ final int rectWidth = rect.width();
+ final int rectHeight = rect.height();
+ final int viewWidth = getViewWidth();
+ final int viewHeight = getViewHeightWithTitle();
+ float scale = Math.min((float) viewWidth / rectWidth, (float) viewHeight
+ / rectHeight);
scale = mZoomManager.computeScaleWithLimits(scale);
if (!mZoomManager.willScaleTriggerZoom(scale)) {
- pinScrollTo(contentToViewX(docX + docWidth / 2) - viewWidth / 2,
- contentToViewY(docY + docHeight / 2) - viewHeight / 2,
+ pinScrollTo(contentToViewX(rect.left + rectWidth / 2) - viewWidth / 2,
+ contentToViewY(rect.top + rectHeight / 2) - viewHeight / 2,
true, 0);
} else {
float actualScale = mZoomManager.getScale();
- float oldScreenX = docX * actualScale - mScrollX;
- float rectViewX = docX * scale;
- float rectViewWidth = docWidth * scale;
+ float oldScreenX = rect.left * actualScale - mScrollX;
+ float rectViewX = rect.left * scale;
+ float rectViewWidth = rectWidth * scale;
float newMaxWidth = mContentWidth * scale;
float newScreenX = (viewWidth - rectViewWidth) / 2;
// pin the newX to the WebView
@@ -6770,10 +6787,10 @@
}
float zoomCenterX = (oldScreenX * scale - newScreenX * actualScale)
/ (scale - actualScale);
- float oldScreenY = docY * actualScale + getTitleHeight()
+ float oldScreenY = rect.top * actualScale + getTitleHeight()
- mScrollY;
- float rectViewY = docY * scale + getTitleHeight();
- float rectViewHeight = docHeight * scale;
+ float rectViewY = rect.top * scale + getTitleHeight();
+ float rectViewHeight = rectHeight * scale;
float newMaxHeight = mContentHeight * scale + getTitleHeight();
float newScreenY = (viewHeight - rectViewHeight) / 2;
// pin the newY to the WebView
@@ -7506,8 +7523,7 @@
break;
case CENTER_FIT_RECT:
- Rect r = (Rect)msg.obj;
- centerFitRect(r.left, r.top, r.width(), r.height());
+ centerFitRect((Rect)msg.obj);
break;
case SET_SCROLLBAR_MODES:
@@ -8150,6 +8166,7 @@
}
private native int nativeCacheHitFramePointer();
+ private native boolean nativeCacheHitIsPlugin();
private native Rect nativeCacheHitNodeBounds();
private native int nativeCacheHitNodePointer();
/* package */ native void nativeClearCursor();
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index b4a33de..88a54ea 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -20,6 +20,7 @@
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Point;
+import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
@@ -551,12 +552,12 @@
* If the double tap was on a plugin then either zoom to maximize the
* plugin on the screen or scale to overview mode.
*/
- ViewManager.ChildView plugin = mWebView.mViewManager.hitTest(mAnchorX, mAnchorY);
- if (plugin != null) {
- if (mWebView.isPluginFitOnScreen(plugin)) {
+ Rect pluginBounds = mWebView.getPluginBounds(mAnchorX, mAnchorY);
+ if (pluginBounds != null) {
+ if (mWebView.isRectFitOnScreen(pluginBounds)) {
zoomToOverview();
} else {
- mWebView.centerFitRect(plugin.x, plugin.y, plugin.width, plugin.height);
+ mWebView.centerFitRect(pluginBounds);
}
return;
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 7631df4..d8f5972 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2642,6 +2642,7 @@
setPressed(true);
layoutChildren();
positionSelector(mMotionPosition, child);
+ refreshDrawableState();
final int longPressTimeout = ViewConfiguration.getLongPressTimeout();
final boolean longClickable = isLongClickable();
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 4d63cf4..2c53005 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -46,8 +46,8 @@
* displayed. Also the minimal and maximal date from which dates to be selected
* can be customized.
* <p>
- * See the <a href="{@docRoot}
- * resources/tutorials/views/hello-datepicker.html">Date Picker tutorial</a>.
+ * See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date
+ * Picker tutorial</a>.
* </p>
* <p>
* For a dialog using this view, see {@link android.app.DatePickerDialog}.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index de886d8..1895d79 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7931,9 +7931,6 @@
max = Math.max(0, Math.max(selStart, selEnd));
}
- ClipboardManager clipboard = (ClipboardManager)getContext()
- .getSystemService(Context.CLIPBOARD_SERVICE);
-
switch (id) {
case ID_COPY_URL:
URLSpan[] urls = ((Spanned) mText).getSpans(min, max, URLSpan.class);
@@ -8402,8 +8399,12 @@
*/
public void updatePosition(HandleView handle, int x, int y);
+ public void updateOffset(HandleView handle, int offset);
+
public void updatePosition();
+ public int getCurrentOffset(HandleView handle);
+
/**
* This method is called by {@link #onTouchEvent(MotionEvent)} and gives the controller
* a chance to become active and/or visible.
@@ -8420,7 +8421,7 @@
}
private class PastePopupMenu implements OnClickListener {
- private PopupWindow mContainer;
+ private final PopupWindow mContainer;
private int mPositionX;
private int mPositionY;
private View mPasteView, mNoPasteView;
@@ -8519,12 +8520,11 @@
}
private class HandleView extends View {
- private boolean mPositionOnTop = false;
private Drawable mDrawable;
- private PopupWindow mContainer;
+ private final PopupWindow mContainer;
private int mPositionX;
private int mPositionY;
- private CursorController mController;
+ private final CursorController mController;
private boolean mIsDragging;
private float mTouchToWindowOffsetX;
private float mTouchToWindowOffsetY;
@@ -8541,6 +8541,46 @@
private PastePopupMenu mPastePopupWindow;
private Runnable mLongPressCallback;
+ // Touch-up filter: number of previous positions remembered
+ private static final int HISTORY_SIZE = 5;
+ private static final int TOUCH_UP_FILTER_DELAY = 150;
+ private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE];
+ private final int[] mPreviousOffsets = new int[HISTORY_SIZE];
+ private int mPreviousOffsetIndex = 0;
+ private int mNumberPreviousOffsets = 0;
+
+ public void startTouchUpFilter(int offset) {
+ mNumberPreviousOffsets = 0;
+ addPositionToTouchUpFilter(offset);
+ }
+
+ public void addPositionToTouchUpFilter(int offset) {
+ if (mNumberPreviousOffsets > 0 &&
+ mPreviousOffsets[mPreviousOffsetIndex] == offset) {
+ // Make sure only actual changes of position are recorded.
+ return;
+ }
+
+ mPreviousOffsetIndex = (mPreviousOffsetIndex + 1) % HISTORY_SIZE;
+ mPreviousOffsets[mPreviousOffsetIndex] = offset;
+ mPreviousOffsetsTimes[mPreviousOffsetIndex] = SystemClock.uptimeMillis();
+ mNumberPreviousOffsets++;
+ }
+
+ public void filterOnTouchUp() {
+ final long now = SystemClock.uptimeMillis();
+ int i = 0;
+ int index = 0;
+ final int iMax = Math.min(mNumberPreviousOffsets, HISTORY_SIZE);
+ while (i < iMax) {
+ index = (mPreviousOffsetIndex - i + HISTORY_SIZE) % HISTORY_SIZE;
+ if ((now - mPreviousOffsetsTimes[index]) >= TOUCH_UP_FILTER_DELAY) break;
+ i++;
+ }
+
+ mController.updateOffset(this, mPreviousOffsets[index]);
+ }
+
public static final int LEFT = 0;
public static final int CENTER = 1;
public static final int RIGHT = 2;
@@ -8736,20 +8776,14 @@
@Override
protected void onDraw(Canvas c) {
mDrawable.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
- if (mPositionOnTop) {
- c.save();
- c.rotate(180, (mRight - mLeft) / 2, (mBottom - mTop) / 2);
- mDrawable.draw(c);
- c.restore();
- } else {
- mDrawable.draw(c);
- }
+ mDrawable.draw(c);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
+ startTouchUpFilter(mController.getCurrentOffset(this));
mDownPositionX = ev.getRawX();
mDownPositionY = ev.getRawY();
mTouchToWindowOffsetX = mDownPositionX - mPositionX;
@@ -8806,6 +8840,7 @@
}
}
}
+ filterOnTouchUp();
mIsDragging = false;
break;
@@ -8823,6 +8858,7 @@
}
void positionAtCursor(final int offset, boolean bottom) {
+ addPositionToTouchUpFilter(offset);
final int width = mDrawable.getIntrinsicWidth();
final int height = mDrawable.getIntrinsicHeight();
final int line = mLayout.getLineForOffset(offset);
@@ -8938,12 +8974,16 @@
int offset = getHysteresisOffset(x, y, previousOffset);
if (offset != previousOffset) {
- Selection.setSelection((Spannable) mText, offset);
- updatePosition();
+ updateOffset(handle, offset);
}
hideDelayed();
}
+ public void updateOffset(HandleView handle, int offset) {
+ Selection.setSelection((Spannable) mText, offset);
+ updatePosition();
+ }
+
public void updatePosition() {
final int offset = getSelectionStart();
@@ -8957,6 +8997,10 @@
getHandle().positionAtCursor(offset, true);
}
+ public int getCurrentOffset(HandleView handle) {
+ return getSelectionStart();
+ }
+
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
@@ -9067,6 +9111,20 @@
updatePosition();
}
+ public void updateOffset(HandleView handle, int offset) {
+ int start = getSelectionStart();
+ int end = getSelectionEnd();
+
+ if (mStartHandle == handle) {
+ start = offset;
+ } else {
+ end = offset;
+ }
+
+ Selection.setSelection((Spannable) mText, start, end);
+ updatePosition();
+ }
+
public void updatePosition() {
if (!isShowing()) {
return;
@@ -9087,6 +9145,10 @@
mEndHandle.positionAtCursor(selectionEnd, true);
}
+ public int getCurrentOffset(HandleView handle) {
+ return mStartHandle == handle ? getSelectionStart() : getSelectionEnd();
+ }
+
public boolean onTouchEvent(MotionEvent event) {
// This is done even when the View does not have focus, so that long presses can start
// selection and tap can move cursor from this tap position.
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index e47d91c..491a388 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -517,6 +517,11 @@
}
}
+static jboolean nativeIsSeekable(JNIEnv* env, jobject, jobject fileDescriptor) {
+ jint descriptor = env->GetIntField(fileDescriptor, gFileDescriptor_descriptor);
+ return ::lseek64(descriptor, 0, SEEK_CUR) != -1 ? JNI_TRUE : JNI_FALSE;
+}
+
///////////////////////////////////////////////////////////////////////////////
static JNINativeMethod gMethods[] = {
@@ -546,6 +551,11 @@
},
{ "nativeSetDefaultConfig", "(I)V", (void*)nativeSetDefaultConfig },
+
+ { "nativeIsSeekable",
+ "(Ljava/io/FileDescriptor;)Z",
+ (void*)nativeIsSeekable
+ },
};
static JNINativeMethod gOptionsMethods[] = {
diff --git a/core/res/res/color/secondary_text_holo_dark.xml b/core/res/res/color/secondary_text_holo_dark.xml
index 881a1de3..7c564f7 100644
--- a/core/res/res/color/secondary_text_holo_dark.xml
+++ b/core/res/res/color/secondary_text_holo_dark.xml
@@ -17,11 +17,11 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
<item android:state_window_focused="false" android:color="@android:color/dim_foreground_holo_dark"/>
- <item android:state_selected="true" android:state_enabled="false" android:color="@android:color/dim_foreground_inverse_disabled_holo_dark"/>
- <item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_inverse_disabled_holo_dark"/>
- <item android:state_selected="true" android:color="@android:color/dim_foreground_inverse_holo_dark"/>
- <item android:state_activated="true" android:color="@android:color/bright_foreground_inverse_holo_dark"/>
- <item android:state_pressed="true" android:color="@android:color/dim_foreground_inverse_holo_dark"/>
+ <item android:state_selected="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
+ <item android:state_pressed="true" android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
+ <item android:state_selected="true" android:color="@android:color/dim_foreground_holo_dark"/>
+ <item android:state_activated="true" android:color="@android:color/bright_foreground_holo_dark"/>
+ <item android:state_pressed="true" android:color="@android:color/dim_foreground_holo_dark"/>
<item android:state_enabled="false" android:color="@android:color/dim_foreground_disabled_holo_dark"/>
<item android:color="@android:color/dim_foreground_holo_dark"/> <!-- not selected -->
</selector>
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_0.png b/core/res/res/drawable-hdpi/stat_sys_battery_0.png
index 3ed0105..82f2509 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_0.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_10.png b/core/res/res/drawable-hdpi/stat_sys_battery_10.png
old mode 100644
new mode 100755
index c81616b..4486553
--- a/core/res/res/drawable-hdpi/stat_sys_battery_10.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_10.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_100.png b/core/res/res/drawable-hdpi/stat_sys_battery_100.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_20.png b/core/res/res/drawable-hdpi/stat_sys_battery_20.png
old mode 100644
new mode 100755
index eb5ef09..c8f9c92
--- a/core/res/res/drawable-hdpi/stat_sys_battery_20.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_20.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_40.png b/core/res/res/drawable-hdpi/stat_sys_battery_40.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_60.png b/core/res/res/drawable-hdpi/stat_sys_battery_60.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_80.png b/core/res/res/drawable-hdpi/stat_sys_battery_80.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
old mode 100644
new mode 100755
index 9a6c683..c7464f7
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png
old mode 100644
new mode 100755
index c40c622..997feb3
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png
old mode 100644
new mode 100755
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png b/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png
old mode 100644
new mode 100755
index 1a9abaf..dadfe8d
--- a/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/btn_code_lock_default.png b/core/res/res/drawable-xlarge-hdpi/btn_code_lock_default.png
new file mode 100644
index 0000000..719eb89
--- /dev/null
+++ b/core/res/res/drawable-xlarge-hdpi/btn_code_lock_default.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/btn_code_lock_touched.png b/core/res/res/drawable-xlarge-hdpi/btn_code_lock_touched.png
new file mode 100644
index 0000000..719eb89
--- /dev/null
+++ b/core/res/res/drawable-xlarge-hdpi/btn_code_lock_touched.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_drag_direction_green_up.png b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_drag_direction_green_up.png
new file mode 100644
index 0000000..c605607
--- /dev/null
+++ b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_drag_direction_green_up.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_drag_direction_red_up.png
new file mode 100644
index 0000000..a798863
--- /dev/null
+++ b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_drag_direction_red_up.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_default.png
new file mode 100644
index 0000000..07e6165
--- /dev/null
+++ b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_default.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_green.png
new file mode 100644
index 0000000..ec17841
--- /dev/null
+++ b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_green.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_red.png
new file mode 100644
index 0000000..a0cb1ec
--- /dev/null
+++ b/core/res/res/drawable-xlarge-hdpi/indicator_code_lock_point_area_red.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_code_lock_default.png b/core/res/res/drawable-xlarge-mdpi/btn_code_lock_default.png
index eb4e0be..45cc20d 100644
--- a/core/res/res/drawable-xlarge-mdpi/btn_code_lock_default.png
+++ b/core/res/res/drawable-xlarge-mdpi/btn_code_lock_default.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_code_lock_touched.png b/core/res/res/drawable-xlarge-mdpi/btn_code_lock_touched.png
index e56ae5b..45cc20d 100644
--- a/core/res/res/drawable-xlarge-mdpi/btn_code_lock_touched.png
+++ b/core/res/res/drawable-xlarge-mdpi/btn_code_lock_touched.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_green_up.png b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_green_up.png
index 8c3e363..0bc86c3 100644
--- a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_green_up.png
+++ b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_green_up.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_red_up.png
index 7b3e41b..2ab4547 100644
--- a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_red_up.png
+++ b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_drag_direction_red_up.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_default.png
index f163742..fe72d00 100644
--- a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_default.png
+++ b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_default.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_green.png
index 37abb2f..be666c6 100644
--- a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_green.png
+++ b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_green.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_red.png
index c6f6fc2..9627197 100644
--- a/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_red.png
+++ b/core/res/res/drawable-xlarge-mdpi/indicator_code_lock_point_area_red.png
Binary files differ
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index dd6bf19..cffee5f 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -564,11 +564,22 @@
* @return the decoded bitmap, or null
*/
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {
- Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
- if (bm == null && opts != null && opts.inBitmap != null) {
- throw new IllegalArgumentException("Problem decoding into existing bitmap");
+ if (nativeIsSeekable(fd)) {
+ Bitmap bm = nativeDecodeFileDescriptor(fd, outPadding, opts);
+ if (bm == null && opts != null && opts.inBitmap != null) {
+ throw new IllegalArgumentException("Problem decoding into existing bitmap");
+ }
+ return finishDecode(bm, outPadding, opts);
+ } else {
+ FileInputStream fis = new FileInputStream(fd);
+ try {
+ return decodeStream(fis, outPadding, opts);
+ } finally {
+ try {
+ fis.close();
+ } catch (Throwable t) {/* ignore */}
+ }
}
- return finishDecode(bm, outPadding, opts);
}
/**
@@ -615,4 +626,5 @@
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts);
private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad);
+ private static native boolean nativeIsSeekable(FileDescriptor fd);
}
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 1ab2109..042f6c7 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -471,45 +471,42 @@
ScriptC *s,
const char *resName,
const char *cacheDir) {
- {
- s->mBccScript = bccCreateScript();
+ s->mBccScript = bccCreateScript();
- s->mEnviroment.mIsThreadable = true;
+ s->mEnviroment.mIsThreadable = true;
- bccRegisterSymbolCallback(s->mBccScript, symbolLookup, s);
+ bccRegisterSymbolCallback(s->mBccScript, symbolLookup, s);
- if (bccReadBC(s->mBccScript,
- resName,
- s->mEnviroment.mScriptText,
- s->mEnviroment.mScriptTextLength, 0) != 0) {
- LOGE("bcc: FAILS to read bitcode");
- // Handle Fatal Error
- }
+ if (bccReadBC(s->mBccScript,
+ resName,
+ s->mEnviroment.mScriptText,
+ s->mEnviroment.mScriptTextLength, 0) != 0) {
+ LOGE("bcc: FAILS to read bitcode");
+ // Handle Fatal Error
+ }
#if 1
- if (bccLinkBC(s->mBccScript,
- resName,
- NULL /*rs_runtime_lib_bc*/,
- 1 /*rs_runtime_lib_bc_size*/
- /*"1" means skip buffer here, and let libbcc decide*/,
- 0) != 0) {
- LOGE("bcc: FAILS to link bitcode");
- // Handle Fatal Error
- }
-#endif
- char *cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
-
- if (bccPrepareExecutable(s->mBccScript, cachePath, 0) != 0) {
- LOGE("bcc: FAILS to prepare executable");
- // Handle Fatal Error
- }
-
- free(cachePath);
-
- s->mProgram.mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(s->mBccScript, "root"));
- s->mProgram.mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(s->mBccScript, "init"));
+ if (bccLinkBC(s->mBccScript,
+ resName,
+ NULL /*rs_runtime_lib_bc*/,
+ 1 /*rs_runtime_lib_bc_size*/
+ /*"1" means skip buffer here, and let libbcc decide*/,
+ 0) != 0) {
+ LOGE("bcc: FAILS to link bitcode");
+ // Handle Fatal Error
}
- LOGV("%p ScriptCState::runCompiler root %p, init %p", rsc, s->mProgram.mRoot, s->mProgram.mInit);
+#endif
+ char *cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
+
+ if (bccPrepareExecutable(s->mBccScript, cachePath, 0) != 0) {
+ LOGE("bcc: FAILS to prepare executable");
+ // Handle Fatal Error
+ }
+
+ free(cachePath);
+
+ s->mProgram.mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(s->mBccScript, "root"));
+ s->mProgram.mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(s->mBccScript, "init"));
if (s->mProgram.mInit) {
s->mProgram.mInit();
@@ -537,66 +534,62 @@
s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
- if (s->mProgram.mRoot) {
- const static int pragmaMax = 16;
- size_t pragmaCount = bccGetPragmaCount(s->mBccScript);
- char const *keys[pragmaMax];
- char const *values[pragmaMax];
- bccGetPragmaList(s->mBccScript, pragmaMax, keys, values);
+ const static int pragmaMax = 16;
+ size_t pragmaCount = bccGetPragmaCount(s->mBccScript);
+ char const *keys[pragmaMax];
+ char const *values[pragmaMax];
+ bccGetPragmaList(s->mBccScript, pragmaMax, keys, values);
- for (size_t i=0; i < pragmaCount; ++i) {
- //LOGE("pragma %s %s", keys[i], values[i]);
- if (!strcmp(keys[i], "version")) {
+ for (size_t i=0; i < pragmaCount; ++i) {
+ //LOGE("pragma %s %s", keys[i], values[i]);
+ if (!strcmp(keys[i], "version")) {
+ // TODO: Verify that version is correct
+ continue;
+ }
+
+ if (!strcmp(keys[i], "stateVertex")) {
+ if (!strcmp(values[i], "default")) {
continue;
}
-
- if (!strcmp(keys[i], "stateVertex")) {
- if (!strcmp(values[i], "default")) {
- continue;
- }
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mVertex.clear();
- continue;
- }
- LOGE("Unreconized value %s passed to stateVertex", values[i]);
+ if (!strcmp(values[i], "parent")) {
+ s->mEnviroment.mVertex.clear();
+ continue;
}
-
- if (!strcmp(keys[i], "stateRaster")) {
- if (!strcmp(values[i], "default")) {
- continue;
- }
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mRaster.clear();
- continue;
- }
- LOGE("Unreconized value %s passed to stateRaster", values[i]);
- }
-
- if (!strcmp(keys[i], "stateFragment")) {
- if (!strcmp(values[i], "default")) {
- continue;
- }
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mFragment.clear();
- continue;
- }
- LOGE("Unreconized value %s passed to stateFragment", values[i]);
- }
-
- if (!strcmp(keys[i], "stateStore")) {
- if (!strcmp(values[i], "default")) {
- continue;
- }
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mFragmentStore.clear();
- continue;
- }
- LOGE("Unreconized value %s passed to stateStore", values[i]);
- }
+ LOGE("Unreconized value %s passed to stateVertex", values[i]);
}
- } else {
- LOGE("bcc: FAILS to prepare executable");
- // Handle Fatal Error
+
+ if (!strcmp(keys[i], "stateRaster")) {
+ if (!strcmp(values[i], "default")) {
+ continue;
+ }
+ if (!strcmp(values[i], "parent")) {
+ s->mEnviroment.mRaster.clear();
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateRaster", values[i]);
+ }
+
+ if (!strcmp(keys[i], "stateFragment")) {
+ if (!strcmp(values[i], "default")) {
+ continue;
+ }
+ if (!strcmp(values[i], "parent")) {
+ s->mEnviroment.mFragment.clear();
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateFragment", values[i]);
+ }
+
+ if (!strcmp(keys[i], "stateStore")) {
+ if (!strcmp(values[i], "default")) {
+ continue;
+ }
+ if (!strcmp(values[i], "parent")) {
+ s->mEnviroment.mFragmentStore.clear();
+ continue;
+ }
+ LOGE("Unreconized value %s passed to stateStore", values[i]);
+ }
}
}
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
index 993ea55..3359602 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
index 69bc161..7012ddc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -188,6 +188,12 @@
Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY, ID_IME_BUTTON_VISIBILITY_AUTO);
}
+ public void setIconImage(int resId) {
+ if (mIcon != null) {
+ mIcon.setImageResource(resId);
+ }
+ }
+
public void setIMEButtonVisible(IBinder token, boolean keyboardVisible) {
mToken = token;
mKeyboardVisible = keyboardVisible;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index add67b1..cc200e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.provider.Settings;
@@ -53,11 +52,12 @@
new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
private final HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>> mRadioViewAndImiMap =
new HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>>();
- private final PackageManager mPackageManager;
private Context mContext;
private IBinder mToken;
+ private InputMethodButton mInputMethodSwitchButton;
private LinearLayout mInputMethodMenuList;
+ private PackageManager mPackageManager;
private String mEnabledInputMethodAndSubtypesCacheStr;
private View mConfigureImeShortcut;
@@ -69,7 +69,6 @@
super(context, attrs, defStyle);
mContext = context;
mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
- mPackageManager = context.getPackageManager();
}
@Override
@@ -90,8 +89,17 @@
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
- if (visibility == View.VISIBLE && changedView == this) {
- updateUiElements();
+ if (changedView == this) {
+ if (visibility == View.VISIBLE) {
+ updateUiElements();
+ if (mInputMethodSwitchButton != null) {
+ mInputMethodSwitchButton.setIconImage(R.drawable.ic_sysbar_ime_pressed);
+ }
+ } else {
+ if (mInputMethodSwitchButton != null) {
+ mInputMethodSwitchButton.setIconImage(R.drawable.ic_sysbar_ime);
+ }
+ }
}
}
@@ -180,6 +188,8 @@
// TODO: Reuse subtype views.
mInputMethodMenuList.removeAllViews();
mRadioViewAndImiMap.clear();
+ mPackageManager = mContext.getPackageManager();
+
HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs
= getEnabledInputMethodAndSubtypeList();
// TODO: Sort by alphabet and mode.
@@ -198,10 +208,14 @@
updateRadioButtons();
}
- public void setIMEToken(IBinder token) {
+ public void setImeToken(IBinder token) {
mToken = token;
}
+ public void setImeSwitchButton(InputMethodButton imb) {
+ mInputMethodSwitchButton = imb;
+ }
+
private void setInputMethodAndSubtype(InputMethodInfo imi, InputMethodSubtype subtype) {
if (mToken != null) {
mImm.setInputMethodAndSubtype(mToken, imi.getId(), subtype);
@@ -308,6 +322,10 @@
private CharSequence getSubtypeName(InputMethodInfo imi, InputMethodSubtype subtype) {
if (imi == null || subtype == null) return null;
+ if (DEBUG) {
+ Log.d(TAG, "Get text from: " + imi.getPackageName() + subtype.getNameResId()
+ + imi.getServiceInfo().applicationInfo);
+ }
// TODO: Change the language of subtype name according to subtype's locale.
return mPackageManager.getText(
imi.getPackageName(), subtype.getNameResId(), imi.getServiceInfo().applicationInfo);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 825877a..6db74d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -272,6 +272,7 @@
mInputMethodsPanel.setVisibility(View.GONE);
mInputMethodsPanel.setOnTouchListener(new TouchOutsideListener(
MSG_CLOSE_INPUT_METHODS_PANEL, mInputMethodsPanel));
+ mInputMethodsPanel.setImeSwitchButton(mInputMethodSwitchButton);
mStatusBarView.setIgnoreChildren(3, mInputMethodSwitchButton, mInputMethodsPanel);
lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -853,7 +854,7 @@
if (oldVisibility != mInputMethodSwitchButton.getVisibility()) {
updateNotificationIcons();
}
- mInputMethodsPanel.setIMEToken(token);
+ mInputMethodsPanel.setImeToken(token);
mBackButton.setImageResource(
visible ? R.drawable.ic_sysbar_back_ime : R.drawable.ic_sysbar_back);
if (FAKE_SPACE_BAR) {
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 7b4f246..4d40620 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -2049,8 +2049,9 @@
for (int i = 0; i < N; ++i) {
InputMethodSubtype subtype = subtypes.get(i);
final String subtypeLocale = subtype.getLocale();
- // An applicable subtype should match "mode".
- if (subtypes.get(i).getMode().equalsIgnoreCase(mode)) {
+ // An applicable subtype should match "mode". If mode is null, mode will be ignored,
+ // and all subtypes with all modes can be candidates.
+ if (mode == null || subtypes.get(i).getMode().equalsIgnoreCase(mode)) {
if (firstMatchedModeSubtype == null) {
firstMatchedModeSubtype = subtype;
}
@@ -2175,11 +2176,24 @@
InputMethodInfo imi = mMethodMap.get(lastInputMethodId);
if (imi != null) {
// If there are no selected subtypes, the framework will try to find
- // the most applicable subtype from all subtypes whose mode is
- // SUBTYPE_MODE_KEYBOARD. This is an exceptional case, so we will hardcode
- // the mode.
- mCurrentSubtype = findLastResortApplicableSubtypeLocked(
- mRes, imi.getSubtypes(), SUBTYPE_MODE_KEYBOARD, null, true);
+ // the most applicable subtype from explicitly or implicitly enabled
+ // subtypes.
+ List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
+ getEnabledInputMethodSubtypeList(imi, true);
+ // If there is only one explicitly or implicitly enabled subtype,
+ // just returns it.
+ if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
+ mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
+ } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
+ mCurrentSubtype = findLastResortApplicableSubtypeLocked(
+ mRes, explicitlyOrImplicitlyEnabledSubtypes,
+ SUBTYPE_MODE_KEYBOARD, null, true);
+ if (mCurrentSubtype == null) {
+ mCurrentSubtype = findLastResortApplicableSubtypeLocked(
+ mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null,
+ true);
+ }
+ }
}
} else {
mCurrentSubtype =
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 166dbc3..8d194925 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -80,6 +80,7 @@
private final Object mProjectKey;
private final DisplayMetrics mMetrics;
private final RenderResources mRenderResources;
+ private final ApplicationInfo mApplicationInfo;
private final Map<Object, Map<String, String>> mDefaultPropMaps =
new IdentityHashMap<Object, Map<String,String>>();
@@ -112,10 +113,12 @@
* value is the resource value.
* @param styleInheritanceMap
* @param projectCallback
+ * @param targetSdkVersion the targetSdkVersion of the application.
*/
public BridgeContext(Object projectKey, DisplayMetrics metrics,
RenderResources renderResources,
- IProjectCallback projectCallback) {
+ IProjectCallback projectCallback,
+ int targetSdkVersion) {
mProjectKey = projectKey;
mMetrics = metrics;
mProjectCallback = projectCallback;
@@ -124,6 +127,9 @@
mFragments.mCurState = Fragment.CREATED;
mFragments.mActivity = this;
+
+ mApplicationInfo = new ApplicationInfo();
+ mApplicationInfo.targetSdkVersion = targetSdkVersion;
}
/**
@@ -836,7 +842,7 @@
@Override
public ApplicationInfo getApplicationInfo() {
- return new ApplicationInfo();
+ return mApplicationInfo;
}
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index e5951f6..63d52e9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -67,8 +67,10 @@
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TabWidget;
+import android.widget.TabHost.TabSpec;
import java.awt.Color;
import java.awt.Graphics2D;
@@ -170,7 +172,7 @@
// build the context
mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
- mParams.getProjectCallback());
+ mParams.getProjectCallback(), mParams.getTargetSdkVersion());
setUp();
@@ -918,7 +920,7 @@
/**
* Returns the top screen offset. This depends on whether the current theme defines the user
* of the title and status bars.
- * @param resolver The {@link ResourceResolver}
+ * @param resolver The {@link RenderResources}
* @param metrics The display metrics
* @return the pixel height offset
*/
@@ -1047,28 +1049,36 @@
// now process the content of the framelayout and dynamically create tabs for it.
final int count = content.getChildCount();
- if (count == 0) {
- throw new PostInflateException(
- "The FrameLayout for the TabHost has no content. Rendering failed.\n");
- }
-
// this must be called before addTab() so that the TabHost searches its TabWidget
// and FrameLayout.
tabHost.setup();
- // for each child of the framelayout, add a new TabSpec
- for (int i = 0 ; i < count ; i++) {
- View child = content.getChildAt(i);
- String tabSpec = String.format("tab_spec%d", i+1);
- int id = child.getId();
- String[] resource = projectCallback.resolveResourceValue(id);
- String name;
- if (resource != null) {
- name = resource[0]; // 0 is resource name, 1 is resource type.
- } else {
- name = String.format("Tab %d", i+1); // default name if id is unresolved.
+ if (count == 0) {
+ // Create a dummy child to get a single tab
+ TabSpec spec = tabHost.newTabSpec("tag").setIndicator("Tab Label",
+ tabHost.getResources().getDrawable(android.R.drawable.ic_menu_info_details))
+ .setContent(new TabHost.TabContentFactory() {
+ public View createTabContent(String tag) {
+ return new LinearLayout(mContext);
+ }
+ });
+ tabHost.addTab(spec);
+ return;
+ } else {
+ // for each child of the framelayout, add a new TabSpec
+ for (int i = 0 ; i < count ; i++) {
+ View child = content.getChildAt(i);
+ String tabSpec = String.format("tab_spec%d", i+1);
+ int id = child.getId();
+ String[] resource = projectCallback.resolveResourceValue(id);
+ String name;
+ if (resource != null) {
+ name = resource[0]; // 0 is resource name, 1 is resource type.
+ } else {
+ name = String.format("Tab %d", i+1); // default name if id is unresolved.
+ }
+ tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
}
- tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
}
}
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
index 3af6e78..dc66989 100644
--- a/voip/java/com/android/server/sip/SipService.java
+++ b/voip/java/com/android/server/sip/SipService.java
@@ -105,7 +105,7 @@
if (SipManager.isApiSupported(context)) {
ServiceManager.addService("sip", new SipService(context));
context.sendBroadcast(new Intent(SipManager.ACTION_SIP_SERVICE_UP));
- if (DEBUG) Log.i(TAG, "SIP service started");
+ if (DEBUG) Log.d(TAG, "SIP service started");
}
}
@@ -113,10 +113,6 @@
if (DEBUG) Log.d(TAG, " service started!");
mContext = context;
mConnectivityReceiver = new ConnectivityReceiver();
- context.registerReceiver(mConnectivityReceiver,
- new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
- context.registerReceiver(mWifiStateReceiver,
- new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
mMyWakeLock = new SipWakeLock((PowerManager)
context.getSystemService(Context.POWER_SERVICE));
@@ -124,7 +120,7 @@
mWifiOnly = SipManager.isSipWifiOnly(context);
}
- BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -147,6 +143,20 @@
}
};
+ private void registerReceivers() {
+ mContext.registerReceiver(mConnectivityReceiver,
+ new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+ mContext.registerReceiver(mWifiStateReceiver,
+ new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
+ if (DEBUG) Log.d(TAG, " +++ register receivers");
+ }
+
+ private void unregisterReceivers() {
+ mContext.unregisterReceiver(mConnectivityReceiver);
+ mContext.unregisterReceiver(mWifiStateReceiver);
+ if (DEBUG) Log.d(TAG, " --- unregister receivers");
+ }
+
private MyExecutor getExecutor() {
// create mExecutor lazily
if (mExecutor == null) mExecutor = new MyExecutor();
@@ -166,12 +176,14 @@
return profiles.toArray(new SipProfile[profiles.size()]);
}
- public void open(SipProfile localProfile) {
+ public synchronized void open(SipProfile localProfile) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.USE_SIP, null);
localProfile.setCallingUid(Binder.getCallingUid());
try {
+ boolean addingFirstProfile = mSipGroups.isEmpty();
createGroup(localProfile);
+ if (addingFirstProfile && !mSipGroups.isEmpty()) registerReceivers();
} catch (SipException e) {
Log.e(TAG, "openToMakeCalls()", e);
// TODO: how to send the exception back
@@ -192,8 +204,10 @@
if (DEBUG) Log.d(TAG, "open3: " + localProfile.getUriString() + ": "
+ incomingCallPendingIntent + ": " + listener);
try {
+ boolean addingFirstProfile = mSipGroups.isEmpty();
SipSessionGroupExt group = createGroup(localProfile,
incomingCallPendingIntent, listener);
+ if (addingFirstProfile && !mSipGroups.isEmpty()) registerReceivers();
if (localProfile.getAutoRegistration()) {
group.openToReceiveCalls();
if (mWifiEnabled) grabWifiLock();
@@ -235,6 +249,7 @@
releaseWifiLock();
mMyWakeLock.reset(); // in case there's leak
}
+ if (mSipGroups.isEmpty()) unregisterReceivers();
}
public synchronized boolean isOpened(String localProfileUri) {
@@ -1055,7 +1070,10 @@
// we want to skip the interim ones) but deliver bad news
// immediately
if (connected) {
- if (mTask != null) mTask.cancel();
+ if (mTask != null) {
+ mTask.cancel();
+ mMyWakeLock.release(mTask);
+ }
mTask = new MyTimerTask(type, connected);
mTimer.schedule(mTask, 2 * 1000L);
// hold wakup lock so that we can finish changes before the
@@ -1096,6 +1114,7 @@
if (mTask != this) {
Log.w(TAG, " unexpected task: " + mNetworkType
+ (mConnected ? " CONNECTED" : "DISCONNECTED"));
+ mMyWakeLock.release(this);
return;
}
mTask = null;