summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml37
-rw-r--r--core/java/android/app/DownloadManager.java27
-rw-r--r--core/java/android/content/SharedPreferences.java18
-rw-r--r--core/java/android/os/BatteryManager.java1
-rw-r--r--core/java/android/preference/Preference.java9
-rw-r--r--core/java/android/preference/PreferenceManager.java25
-rwxr-xr-xcore/java/android/view/KeyEvent.java10
-rw-r--r--core/java/android/view/MotionEvent.java10
-rw-r--r--core/java/android/view/ViewConfiguration.java14
-rw-r--r--core/java/android/view/ViewGroup.java10
-rw-r--r--core/java/android/view/WindowManagerPolicy.java3
-rw-r--r--core/java/android/webkit/WebView.java19
-rw-r--r--core/java/android/widget/AbsListView.java36
-rwxr-xr-xcore/java/android/widget/AppSecurityPermissions.java9
-rw-r--r--core/java/android/widget/ListView.java2
-rw-r--r--core/java/android/widget/Scroller.java28
-rw-r--r--core/java/com/android/internal/app/ShutdownThread.java31
-rw-r--r--core/java/com/android/internal/content/SyncStateContentProviderHelper.java133
-rw-r--r--core/res/res/drawable-hdpi/ic_bullet_key_permission.pngbin3255 -> 938 bytes
-rwxr-xr-xcore/res/res/layout/app_perms_summary.xml18
-rw-r--r--graphics/java/android/renderscript/Element.java9
-rw-r--r--graphics/java/android/renderscript/RenderScript.java1
-rw-r--r--include/ui/Input.h11
-rw-r--r--include/ui/InputDispatcher.h96
-rw-r--r--include/ui/InputReader.h47
-rw-r--r--libs/hwui/OpenGLRenderer.cpp40
-rw-r--r--libs/hwui/Program.cpp5
-rw-r--r--libs/hwui/Program.h8
-rw-r--r--libs/hwui/ProgramCache.cpp177
-rw-r--r--libs/hwui/ProgramCache.h62
-rw-r--r--libs/hwui/Snapshot.h12
-rw-r--r--libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java18
-rw-r--r--libs/rs/java/tests/src/com/android/rs/test/primitives.rs6
-rw-r--r--libs/ui/InputDispatcher.cpp680
-rw-r--r--libs/ui/InputReader.cpp82
-rw-r--r--media/mtp/MtpServer.cpp4
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java15
-rw-r--r--preloaded-classes1
-rw-r--r--services/camera/libcameraservice/CameraService.cpp12
-rw-r--r--services/camera/libcameraservice/CameraService.h2
-rw-r--r--services/java/com/android/server/AlarmManagerService.java8
-rw-r--r--services/java/com/android/server/InputManager.java15
-rw-r--r--services/java/com/android/server/WindowManagerService.java14
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java3
-rw-r--r--services/jni/com_android_server_BatteryService.cpp5
-rw-r--r--services/jni/com_android_server_InputManager.cpp259
-rwxr-xr-xservices/jni/com_android_server_location_GpsLocationProvider.cpp56
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java9
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java37
-rwxr-xr-xtelephony/java/com/android/internal/telephony/sip/SipPhone.java49
-rw-r--r--voip/java/com/android/server/sip/SipHelper.java2
51 files changed, 1238 insertions, 947 deletions
diff --git a/api/current.xml b/api/current.xml
index 375448c..1fe1498 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -134225,6 +134225,17 @@
visibility="public"
>
</constructor>
+<field name="BATTERY_HEALTH_COLD"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="BATTERY_HEALTH_DEAD"
type="int"
transient="false"
@@ -225133,6 +225144,19 @@
<parameter name="filterText" type="java.lang.String">
</parameter>
</method>
+<method name="setFriction"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="friction" type="float">
+</parameter>
+</method>
<method name="setItemChecked"
return="void"
abstract="false"
@@ -238694,6 +238718,19 @@
<parameter name="newY" type="int">
</parameter>
</method>
+<method name="setFriction"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="friction" type="float">
+</parameter>
+</method>
<method name="startScroll"
return="void"
abstract="false"
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 2a5181f..b9a541d 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -28,6 +28,7 @@ import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.provider.Downloads;
+import android.util.Log;
import android.util.Pair;
import java.io.File;
@@ -53,6 +54,8 @@ import java.util.Set;
* download in a notification or from the downloads UI.
*/
public class DownloadManager {
+ private static final String TAG = "DownloadManager";
+
/**
* An identifier for a particular download, unique across the system. Clients use this ID to
* make subsequent calls related to the download.
@@ -754,20 +757,11 @@ public class DownloadManager {
* @return the number of downloads actually removed
*/
public int remove(long... ids) {
- StringBuilder whereClause = new StringBuilder();
- String[] whereArgs = new String[ids.length];
-
- whereClause.append(Downloads.Impl._ID + " IN (");
- for (int i = 0; i < ids.length; i++) {
- if (i > 0) {
- whereClause.append(",");
- }
- whereClause.append("?");
- whereArgs[i] = Long.toString(ids[i]);
+ if (ids == null || ids.length == 0) {
+ // called with nothing to remove!
+ throw new IllegalArgumentException("input param 'ids' can't be null");
}
- whereClause.append(")");
-
- return mResolver.delete(mBaseUri, whereClause.toString(), whereArgs);
+ return mResolver.delete(mBaseUri, getWhereClauseForIds(ids), getWhereArgsForIds(ids));
}
/**
@@ -834,12 +828,13 @@ public class DownloadManager {
*/
static String getWhereClauseForIds(long[] ids) {
StringBuilder whereClause = new StringBuilder();
- whereClause.append(Downloads.Impl._ID + " IN (");
+ whereClause.append("(");
for (int i = 0; i < ids.length; i++) {
if (i > 0) {
- whereClause.append(",");
+ whereClause.append("OR ");
}
- whereClause.append("?");
+ whereClause.append(Downloads.Impl._ID);
+ whereClause.append(" = ? ");
}
whereClause.append(")");
return whereClause.toString();
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index c0788f5..4d9ee54 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -198,9 +198,21 @@ public interface SharedPreferences {
* {@link #commit} will block until all async commits are
* completed as well as the commit itself.
*
- * <p>If you call this from an {@link android.app.Activity},
- * the base class will wait for any async commits to finish in
- * its {@link android.app.Activity#onPause}.</p>
+ * <p>As {@link SharedPreferences} instances are singletons within
+ * a process, it's safe to replace any instance of {@link #commit} with
+ * {@link #apply} if you were already ignoring the return value.
+ *
+ * <p>You don't need to worry about Android component
+ * lifecycles and their interaction with <code>apply()</code>
+ * writing to disk. The framework makes sure in-flight disk
+ * writes from <code>apply()</code> complete before switching
+ * states.
+ *
+ * <p class='note'>The SharedPreferences.Editor interface
+ * isn't expected to be implemented directly. However, if you
+ * previously did implement it and are now getting errors
+ * about missing <code>apply()</code>, you can simply call
+ * {@link #commit} from <code>apply()</code>.
*/
void apply();
}
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 5fd2246..247b281 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -107,6 +107,7 @@ public class BatteryManager {
public static final int BATTERY_HEALTH_DEAD = 4;
public static final int BATTERY_HEALTH_OVER_VOLTAGE = 5;
public static final int BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
+ public static final int BATTERY_HEALTH_COLD = 7;
// values of the "plugged" field in the ACTION_BATTERY_CHANGED intent.
// These must be powers of 2.
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 17b2e82..12b9f0c 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -1242,7 +1242,14 @@ public class Preference implements Comparable<Preference>, OnDependencyChangeLis
private void tryCommit(SharedPreferences.Editor editor) {
if (mPreferenceManager.shouldCommit()) {
- editor.apply();
+ try {
+ editor.apply();
+ } catch (AbstractMethodError unused) {
+ // The app injected its own pre-Gingerbread
+ // SharedPreferences.Editor implementation without
+ // an apply method.
+ editor.commit();
+ }
}
}
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 42150ed..6562de9 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -461,7 +461,16 @@ public class PreferenceManager {
pm.setSharedPreferencesMode(sharedPreferencesMode);
pm.inflateFromResource(context, resId, null);
- defaultValueSp.edit().putBoolean(KEY_HAS_SET_DEFAULT_VALUES, true).apply();
+ SharedPreferences.Editor editor =
+ defaultValueSp.edit().putBoolean(KEY_HAS_SET_DEFAULT_VALUES, true);
+ try {
+ editor.apply();
+ } catch (AbstractMethodError unused) {
+ // The app injected its own pre-Gingerbread
+ // SharedPreferences.Editor implementation without
+ // an apply method.
+ editor.commit();
+ }
}
}
@@ -496,15 +505,21 @@ public class PreferenceManager {
boolean shouldCommit() {
return !mNoCommit;
}
-
+
private void setNoCommit(boolean noCommit) {
if (!noCommit && mEditor != null) {
- mEditor.apply();
+ try {
+ mEditor.apply();
+ } catch (AbstractMethodError unused) {
+ // The app injected its own pre-Gingerbread
+ // SharedPreferences.Editor implementation without
+ // an apply method.
+ mEditor.commit();
+ }
}
-
mNoCommit = noCommit;
}
-
+
/**
* Returns the activity that shows the preferences. This is useful for doing
* managed queries, but in most cases the use of {@link #getContext()} is
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 912180b..0e5ece1 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -46,10 +46,12 @@ import android.view.KeyCharacterMap.KeyData;
* with the special action {@link #ACTION_MULTIPLE} that either specifies
* that single repeated key code or a sequence of characters to insert.
* </p><p>
- * In general, the framework makes no guarantees that the key events delivered
- * to a view constitute a complete key press. In particular, there is no
- * guarantee that a view will always receive a key event with {@link #ACTION_UP}
- * for each {@link #ACTION_DOWN} that was delivered.
+ * In general, the framework cannot guarantee that the key events it delivers
+ * to a view always constitute complete key sequences since some events may be dropped
+ * or modified by containing views before they are delivered. The view implementation
+ * should be prepared to handle {@link #FLAG_CANCELED} and should tolerate anomalous
+ * situations such as receiving a new {@link #ACTION_DOWN} without first having
+ * received an {@link #ACTION_UP} for the prior key press.
* </p><p>
* Refer to {@link InputDevice} for more information about how different kinds of
* input devices and sources represent keys and buttons.
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index dfbe65c..9411474 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -82,10 +82,12 @@ import android.os.SystemClock;
* }
* }
* </code></pre></p><p>
- * In general, the framework makes no guarantees that the motion events delivered
- * to a view constitute a complete gesture. In particular, there is no
- * guarantee that a view will always receive a motion event with {@link #ACTION_UP}
- * for each {@link #ACTION_DOWN} that was delivered.
+ * In general, the framework cannot guarantee that the motion events it delivers
+ * to a view always constitute a complete motion sequences since some events may be dropped
+ * or modified by containing views before they are delivered. The view implementation
+ * should be prepared to handle {@link #ACTION_CANCEL} and should tolerate anomalous
+ * situations such as receiving a new {@link #ACTION_DOWN} without first having
+ * received an {@link #ACTION_UP} for the prior gesture.
* </p><p>
* Refer to {@link InputDevice} for more information about how different kinds of
* input devices and sources represent pointer coordinates.
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index acdfc28..f413475 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -25,6 +25,20 @@ import android.util.SparseArray;
*/
public class ViewConfiguration {
/**
+ * Expected bit depth of the display panel.
+ *
+ * @hide
+ */
+ public static final float PANEL_BIT_DEPTH = 24;
+
+ /**
+ * Minimum alpha required for a view to draw.
+ *
+ * @hide
+ */
+ public static final float ALPHA_THRESHOLD = 0.5f / PANEL_BIT_DEPTH;
+
+ /**
* Defines the width of the horizontal scrollbar and the height of the vertical scrollbar in
* pixels
*/
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5b3a091..be6aa43 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -69,7 +69,7 @@ import java.util.ArrayList;
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
private static final boolean DBG = false;
-
+
/**
* Views which have been hidden or removed which need to be animated on
* their way out.
@@ -2185,6 +2185,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
(child.mPrivateFlags & DRAW_ANIMATION) == 0) {
return more;
}
+
+ float alpha = child.getAlpha();
+ // Bail out early if the view does not need to be drawn
+ if (alpha <= ViewConfiguration.ALPHA_THRESHOLD) return more;
child.computeScroll();
@@ -2217,8 +2221,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
- float alpha = child.getAlpha();
-
if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) {
int transX = 0;
int transY = 0;
@@ -2253,7 +2255,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (alpha < 1.0f) {
mGroupFlags |= FLAG_CLEAR_TRANSFORMATION;
-
+
if (hasNoCache) {
final int multipliedAlpha = (int) (255 * alpha);
if (!child.onSetAlpha(multipliedAlpha)) {
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 954b3e7..1fd31a3 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -65,6 +65,7 @@ import android.view.animation.Animation;
* @hide
*/
public interface WindowManagerPolicy {
+ // Policy flags. These flags are also defined in frameworks/base/include/ui/Input.h.
public final static int FLAG_WAKE = 0x00000001;
public final static int FLAG_WAKE_DROPPED = 0x00000002;
public final static int FLAG_SHIFT = 0x00000004;
@@ -76,9 +77,11 @@ public interface WindowManagerPolicy {
public final static int FLAG_VIRTUAL = 0x00000100;
public final static int FLAG_INJECTED = 0x01000000;
+ public final static int FLAG_TRUSTED = 0x02000000;
public final static int FLAG_WOKE_HERE = 0x10000000;
public final static int FLAG_BRIGHT_HERE = 0x20000000;
+ public final static int FLAG_PASS_TO_USER = 0x40000000;
public final static boolean WATCH_POINTER = false;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5d68613..8c1e5f7 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -317,6 +317,10 @@ public class WebView extends AbsoluteLayout
// true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
private boolean mAutoRedraw;
+ // Reference to the AlertDialog displayed by InvokeListBox.
+ // It's used to dismiss the dialog in destroy if not done before.
+ private AlertDialog mListBoxDialog = null;
+
static final String LOGTAG = "webview";
private ZoomManager mZoomManager;
@@ -1301,7 +1305,10 @@ public class WebView extends AbsoluteLayout
*/
public void destroy() {
clearHelpers();
-
+ if (mListBoxDialog != null) {
+ mListBoxDialog.dismiss();
+ mListBoxDialog = null;
+ }
if (mWebViewCore != null) {
// Set the handlers to null before destroying WebViewCore so no
// more messages will be posted.
@@ -7263,7 +7270,7 @@ public class WebView extends AbsoluteLayout
EventHub.SINGLE_LISTBOX_CHOICE, -2, 0);
}});
}
- final AlertDialog dialog = b.create();
+ mListBoxDialog = b.create();
listView.setAdapter(adapter);
listView.setFocusableInTouchMode(true);
// There is a bug (1250103) where the checks in a ListView with
@@ -7285,7 +7292,8 @@ public class WebView extends AbsoluteLayout
int position, long id) {
mWebViewCore.sendMessage(
EventHub.SINGLE_LISTBOX_CHOICE, (int)id, 0);
- dialog.dismiss();
+ mListBoxDialog.dismiss();
+ mListBoxDialog = null;
}
});
if (mSelection != -1) {
@@ -7297,13 +7305,14 @@ public class WebView extends AbsoluteLayout
adapter.registerDataSetObserver(observer);
}
}
- dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+ mListBoxDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
mWebViewCore.sendMessage(
EventHub.SINGLE_LISTBOX_CHOICE, -2, 0);
+ mListBoxDialog = null;
}
});
- dialog.show();
+ mListBoxDialog.show();
}
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index c694ff1..2af59f9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2965,7 +2965,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int firstPos = mFirstPosition;
final int lastPos = firstPos + getChildCount() - 1;
- int viewTravelCount = 0;
+ int viewTravelCount;
if (position <= firstPos) {
viewTravelCount = firstPos - position + 1;
mMode = MOVE_UP_POS;
@@ -2998,7 +2998,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int firstPos = mFirstPosition;
final int lastPos = firstPos + getChildCount() - 1;
- int viewTravelCount = 0;
+ int viewTravelCount;
if (position <= firstPos) {
final int boundPosFromLast = lastPos - boundPosition;
if (boundPosFromLast < 1) {
@@ -3059,7 +3059,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int childCount = getChildCount();
final int lastPos = firstPos + childCount - 1;
- int viewTravelCount = 0;
+ int viewTravelCount;
if (position < firstPos) {
viewTravelCount = firstPos - position;
} else if (position > lastPos) {
@@ -3249,6 +3249,20 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
+ * The amount of friction applied to flings. The default value
+ * is {@link ViewConfiguration#getScrollFriction}.
+ *
+ * @return A scalar dimensionless value representing the coefficient of
+ * friction.
+ */
+ public void setFriction(float friction) {
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
+ }
+ mFlingRunnable.mScroller.setFriction(friction);
+ }
+
+ /**
* Smoothly scroll to the specified adapter position. The view will
* scroll such that the indicated position is displayed.
* @param position Scroll to this adapter position.
@@ -3581,22 +3595,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* @return The position of the first (or only) item in the row containing y
*/
abstract int findMotionRow(int y);
-
- /**
- * Find the row closest to y. This row will be used as the motion row when scrolling.
- *
- * @param y Where the user touched
- * @return The position of the first (or only) item in the row closest to y
- */
- int findClosestMotionRow(int y) {
- final int childCount = getChildCount();
- if (childCount == 0) {
- return INVALID_POSITION;
- }
-
- final int motionRow = findMotionRow(y);
- return motionRow != INVALID_POSITION ? motionRow : mFirstPosition + childCount - 1;
- }
/**
* Causes all the views to be rebuilt and redrawn.
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index aa14c81..d3aa42f 100755
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -17,14 +17,14 @@
package android.widget;
import com.android.internal.R;
+
import android.content.Context;
-import android.content.res.Resources;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageParser;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
@@ -329,11 +329,6 @@ public class AppSecurityPermissions implements View.OnClickListener {
TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
- if (dangerous) {
- final Resources resources = context.getResources();
- permGrpView.setTextColor(resources.getColor(R.color.perms_dangerous_grp_color));
- permDescView.setTextColor(resources.getColor(R.color.perms_dangerous_perm_color));
- }
ImageView imgView = (ImageView)permView.findViewById(R.id.perm_icon);
imgView.setImageDrawable(icon);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 7c4897a..b5e103f 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -26,7 +26,6 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
@@ -2980,7 +2979,6 @@ public class ListView extends AbsListView {
if (!mStackFromBottom) {
int bottom;
- final int scrollY = mScrollY;
for (int i = 0; i < count; i++) {
if ((headerDividers || first + i >= headerCount) &&
(footerDividers || first + i < footerLimit)) {
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 4cb0839..d2e6688 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -63,7 +63,8 @@ public class Scroller {
private static final int SCROLL_MODE = 0;
private static final int FLING_MODE = 1;
- private final float mDeceleration;
+ private float mDeceleration;
+ private final float mPpi;
/**
* Create a Scroller with the default duration and interpolator.
@@ -79,13 +80,28 @@ public class Scroller {
public Scroller(Context context, Interpolator interpolator) {
mFinished = true;
mInterpolator = interpolator;
- float ppi = context.getResources().getDisplayMetrics().density * 160.0f;
- mDeceleration = SensorManager.GRAVITY_EARTH // g (m/s^2)
- * 39.37f // inch/meter
- * ppi // pixels per inch
- * ViewConfiguration.getScrollFriction();
+ mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
+ mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
+ }
+
+ /**
+ * The amount of friction applied to flings. The default value
+ * is {@link ViewConfiguration#getScrollFriction}.
+ *
+ * @return A scalar dimensionless value representing the coefficient of
+ * friction.
+ */
+ public final void setFriction(float friction) {
+ computeDeceleration(friction);
}
+ private float computeDeceleration(float friction) {
+ return SensorManager.GRAVITY_EARTH // g (m/s^2)
+ * 39.37f // inch/meter
+ * mPpi // pixels per inch
+ * friction;
+ }
+
/**
*
* Returns whether the scroller has finished scrolling.
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index 8104ece..d6f5db1 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -69,7 +69,8 @@ public final class ShutdownThread extends Thread {
private boolean mActionDone;
private Context mContext;
private PowerManager mPowerManager;
- private PowerManager.WakeLock mWakeLock;
+ private PowerManager.WakeLock mCpuWakeLock;
+ private PowerManager.WakeLock mScreenWakeLock;
private Handler mHandler;
private ShutdownThread() {
@@ -187,20 +188,36 @@ public final class ShutdownThread extends Thread {
pd.show();
- // start the thread that initiates shutdown
sInstance.mContext = context;
sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- sInstance.mWakeLock = null;
+
+ // make sure we never fall asleep again
+ sInstance.mCpuWakeLock = null;
+ try {
+ sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu");
+ sInstance.mCpuWakeLock.setReferenceCounted(false);
+ sInstance.mCpuWakeLock.acquire();
+ } catch (SecurityException e) {
+ Log.w(TAG, "No permission to acquire wake lock", e);
+ sInstance.mCpuWakeLock = null;
+ }
+
+ // also make sure the screen stays on for better user experience
+ sInstance.mScreenWakeLock = null;
if (sInstance.mPowerManager.isScreenOn()) {
try {
- sInstance.mWakeLock = sInstance.mPowerManager.newWakeLock(
- PowerManager.FULL_WAKE_LOCK, "Shutdown");
- sInstance.mWakeLock.acquire();
+ sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock(
+ PowerManager.FULL_WAKE_LOCK, TAG + "-screen");
+ sInstance.mScreenWakeLock.setReferenceCounted(false);
+ sInstance.mScreenWakeLock.acquire();
} catch (SecurityException e) {
Log.w(TAG, "No permission to acquire wake lock", e);
- sInstance.mWakeLock = null;
+ sInstance.mScreenWakeLock = null;
}
}
+
+ // start the thread that initiates shutdown
sInstance.mHandler = new Handler() {
};
sInstance.start();
diff --git a/core/java/com/android/internal/content/SyncStateContentProviderHelper.java b/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
deleted file mode 100644
index 274082c..0000000
--- a/core/java/com/android/internal/content/SyncStateContentProviderHelper.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.content;
-
-import com.android.internal.util.ArrayUtils;
-
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.accounts.Account;
-import android.content.ContentValues;
-import android.provider.SyncStateContract;
-
-/**
- * Extends the schema of a ContentProvider to include the _sync_state table
- * and implements query/insert/update/delete to access that table using the
- * authority "syncstate". This can be used to store the sync state for a
- * set of accounts.
- *
- * @hide
- */
-public class SyncStateContentProviderHelper {
- private static final String SELECT_BY_ACCOUNT =
- SyncStateContract.Columns.ACCOUNT_NAME + "=? AND "
- + SyncStateContract.Columns.ACCOUNT_TYPE + "=?";
-
- private static final String SYNC_STATE_TABLE = "_sync_state";
- private static final String SYNC_STATE_META_TABLE = "_sync_state_metadata";
- private static final String SYNC_STATE_META_VERSION_COLUMN = "version";
-
- private static long DB_VERSION = 1;
-
- private static final String[] ACCOUNT_PROJECTION =
- new String[]{SyncStateContract.Columns.ACCOUNT_NAME,
- SyncStateContract.Columns.ACCOUNT_TYPE};
-
- public static final String PATH = "syncstate";
-
- private static final String QUERY_COUNT_SYNC_STATE_ROWS =
- "SELECT count(*)"
- + " FROM " + SYNC_STATE_TABLE
- + " WHERE " + SyncStateContract.Columns._ID + "=?";
-
- public void createDatabase(SQLiteDatabase db) {
- db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_TABLE);
- db.execSQL("CREATE TABLE " + SYNC_STATE_TABLE + " ("
- + SyncStateContract.Columns._ID + " INTEGER PRIMARY KEY,"
- + SyncStateContract.Columns.ACCOUNT_NAME + " TEXT NOT NULL,"
- + SyncStateContract.Columns.ACCOUNT_TYPE + " TEXT NOT NULL,"
- + SyncStateContract.Columns.DATA + " TEXT,"
- + "UNIQUE(" + SyncStateContract.Columns.ACCOUNT_NAME + ", "
- + SyncStateContract.Columns.ACCOUNT_TYPE + "));");
-
- db.execSQL("DROP TABLE IF EXISTS " + SYNC_STATE_META_TABLE);
- db.execSQL("CREATE TABLE " + SYNC_STATE_META_TABLE + " ("
- + SYNC_STATE_META_VERSION_COLUMN + " INTEGER);");
- ContentValues values = new ContentValues();
- values.put(SYNC_STATE_META_VERSION_COLUMN, DB_VERSION);
- db.insert(SYNC_STATE_META_TABLE, SYNC_STATE_META_VERSION_COLUMN, values);
- }
-
- public void onDatabaseOpened(SQLiteDatabase db) {
- long version = DatabaseUtils.longForQuery(db,
- "SELECT " + SYNC_STATE_META_VERSION_COLUMN + " FROM " + SYNC_STATE_META_TABLE,
- null);
- if (version != DB_VERSION) {
- createDatabase(db);
- }
- }
-
- public Cursor query(SQLiteDatabase db, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- return db.query(SYNC_STATE_TABLE, projection, selection, selectionArgs,
- null, null, sortOrder);
- }
-
- public long insert(SQLiteDatabase db, ContentValues values) {
- return db.replace(SYNC_STATE_TABLE, SyncStateContract.Columns.ACCOUNT_NAME, values);
- }
-
- public int delete(SQLiteDatabase db, String userWhere, String[] whereArgs) {
- return db.delete(SYNC_STATE_TABLE, userWhere, whereArgs);
- }
-
- public int update(SQLiteDatabase db, ContentValues values,
- String selection, String[] selectionArgs) {
- return db.update(SYNC_STATE_TABLE, values, selection, selectionArgs);
- }
-
- public int update(SQLiteDatabase db, long rowId, Object data) {
- if (DatabaseUtils.longForQuery(db, QUERY_COUNT_SYNC_STATE_ROWS,
- new String[]{Long.toString(rowId)}) < 1) {
- return 0;
- }
- db.execSQL("UPDATE " + SYNC_STATE_TABLE
- + " SET " + SyncStateContract.Columns.DATA + "=?"
- + " WHERE " + SyncStateContract.Columns._ID + "=" + rowId,
- new Object[]{data});
- // assume a row was modified since we know it exists
- return 1;
- }
-
- public void onAccountsChanged(SQLiteDatabase db, Account[] accounts) {
- Cursor c = db.query(SYNC_STATE_TABLE, ACCOUNT_PROJECTION, null, null, null, null, null);
- try {
- while (c.moveToNext()) {
- final String accountName = c.getString(0);
- final String accountType = c.getString(1);
- Account account = new Account(accountName, accountType);
- if (!ArrayUtils.contains(accounts, account)) {
- db.delete(SYNC_STATE_TABLE, SELECT_BY_ACCOUNT,
- new String[]{accountName, accountType});
- }
- }
- } finally {
- c.close();
- }
- }
-} \ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/ic_bullet_key_permission.png b/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
index 98d95dc..b6b840a 100644
--- a/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
+++ b/core/res/res/drawable-hdpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/layout/app_perms_summary.xml b/core/res/res/layout/app_perms_summary.xml
index 7160743..bdbbfcb 100755
--- a/core/res/res/layout/app_perms_summary.xml
+++ b/core/res/res/layout/app_perms_summary.xml
@@ -65,21 +65,23 @@
android:layout_marginLeft="16dip"
android:duplicateParentState="true">
- <ImageView
- android:id="@+id/show_more_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
<TextView
android:id="@+id/show_more_text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:duplicateParentState="true"
- android:layout_alignTop="@id/show_more_icon"
+ android:layout_alignTop="@+id/show_more_icon"
android:layout_gravity="center_vertical"
- android:paddingLeft="6dip"
- android:layout_width="match_parent"
+ android:paddingLeft="36dip"
+ android:layout_weight="1"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content" />
+ <ImageView
+ android:id="@id/show_more_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="12dip" />
+
</LinearLayout>
<View
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 91824e6..dc421d8 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -47,7 +47,7 @@ public class Element extends BaseObj {
UNSIGNED_8 (8, 1),
UNSIGNED_16 (9, 2),
UNSIGNED_32 (10, 4),
- //UNSIGNED_64 (11, 8),
+ UNSIGNED_64 (11, 8),
BOOLEAN(12, 1),
@@ -142,6 +142,13 @@ public class Element extends BaseObj {
return rs.mElement_I32;
}
+ public static Element U64(RenderScript rs) {
+ if(rs.mElement_U64 == null) {
+ rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
+ }
+ return rs.mElement_U64;
+ }
+
public static Element I64(RenderScript rs) {
if(rs.mElement_I64 == null) {
rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 2774fea..0f9ed87 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -514,6 +514,7 @@ public class RenderScript {
Element mElement_I16;
Element mElement_U32;
Element mElement_I32;
+ Element mElement_U64;
Element mElement_I64;
Element mElement_F32;
Element mElement_F64;
diff --git a/include/ui/Input.h b/include/ui/Input.h
index ee40b85..8c6018b 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -71,6 +71,8 @@ namespace android {
/*
* Flags that flow alongside events in the input dispatch system to help with certain
* policy decisions such as waking from device sleep.
+ *
+ * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
*/
enum {
/* These flags originate in RawEvents and are generally set in the key map.
@@ -93,6 +95,10 @@ enum {
// Indicates that the input event was injected.
POLICY_FLAG_INJECTED = 0x01000000,
+ // Indicates that the input event is from a trusted source such as a directly attached
+ // input device or an application with system-wide event injection permission.
+ POLICY_FLAG_TRUSTED = 0x02000000,
+
/* These flags are set by the input reader policy as it intercepts each event. */
// Indicates that the screen was off when the event was received and the event
@@ -102,6 +108,11 @@ enum {
// Indicates that the screen was dim when the event was received and the event
// should brighten the device.
POLICY_FLAG_BRIGHT_HERE = 0x20000000,
+
+ // Indicates that the event should be dispatched to applications.
+ // The input event should still be sent to the InputDispatcher so that it can see all
+ // input events received include those that it will not deliver.
+ POLICY_FLAG_PASS_TO_USER = 0x40000000,
};
/*
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index 246df8f..63185d3 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -282,10 +282,35 @@ public:
*/
virtual int32_t getMaxEventsPerSecond() = 0;
+ /* Intercepts a key event immediately before queueing it.
+ * The policy can use this method as an opportunity to perform power management functions
+ * and early event preprocessing such as updating policy flags.
+ *
+ * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
+ * should be dispatched to applications.
+ */
+ virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
+ int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
+ uint32_t& policyFlags) = 0;
+
+ /* Intercepts a generic touch, trackball or other event before queueing it.
+ * The policy can use this method as an opportunity to perform power management functions
+ * and early event preprocessing such as updating policy flags.
+ *
+ * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
+ * should be dispatched to applications.
+ */
+ virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
+
/* Allows the policy a chance to intercept a key before dispatching. */
virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
+ /* Notifies the policy about switch events.
+ */
+ virtual void notifySwitch(nsecs_t when,
+ int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;
+
/* Poke user activity for an event dispatched to a window. */
virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;
@@ -333,6 +358,8 @@ public:
int32_t metaState, int32_t edgeFlags,
uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime) = 0;
+ virtual void notifySwitch(nsecs_t when,
+ int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;
/* Injects an input event and optionally waits for sync.
* The synchronization mode determines whether the method blocks while waiting for
@@ -416,6 +443,8 @@ public:
int32_t metaState, int32_t edgeFlags,
uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
float xPrecision, float yPrecision, nsecs_t downTime);
+ virtual void notifySwitch(nsecs_t when,
+ int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ;
virtual int32_t injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
@@ -458,6 +487,7 @@ private:
mutable int32_t refCount;
int32_t type;
nsecs_t eventTime;
+ uint32_t policyFlags;
InjectionState* injectionState;
bool dispatchInProgress; // initially false, set to true while dispatching
@@ -471,7 +501,6 @@ private:
struct KeyEntry : EventEntry {
int32_t deviceId;
int32_t source;
- uint32_t policyFlags;
int32_t action;
int32_t flags;
int32_t keyCode;
@@ -500,7 +529,6 @@ private:
struct MotionEntry : EventEntry {
int32_t deviceId;
int32_t source;
- uint32_t policyFlags;
int32_t action;
int32_t flags;
int32_t metaState;
@@ -675,7 +703,8 @@ private:
Pool<DispatchEntry> mDispatchEntryPool;
Pool<CommandEntry> mCommandEntryPool;
- void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
+ void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime,
+ uint32_t policyFlags);
void releaseEventEntryInjectionState(EventEntry* entry);
};
@@ -696,21 +725,19 @@ private:
BROKEN
};
+ // Specifies the sources to cancel.
+ enum CancelationOptions {
+ CANCEL_ALL_EVENTS = 0,
+ CANCEL_POINTER_EVENTS = 1,
+ CANCEL_NON_POINTER_EVENTS = 2,
+ };
+
InputState();
~InputState();
// Returns true if there is no state to be canceled.
bool isNeutral() const;
- // Returns true if the input state believes it is out of sync.
- bool isOutOfSync() const;
-
- // Sets the input state to be out of sync if it is not neutral.
- void setOutOfSync();
-
- // Resets the input state out of sync flag.
- void resetOutOfSync();
-
// Records tracking information for an event that has just been published.
// Returns whether the event is consistent with the current input state.
Consistency trackEvent(const EventEntry* entry);
@@ -723,16 +750,17 @@ private:
// Returns whether the event is consistent with the current input state.
Consistency trackMotion(const MotionEntry* entry);
- // Synthesizes cancelation events for the current state.
- void synthesizeCancelationEvents(Allocator* allocator,
- Vector<EventEntry*>& outEvents) const;
+ // Synthesizes cancelation events for the current state and resets the tracked state.
+ void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
+ Vector<EventEntry*>& outEvents, CancelationOptions options);
// Clears the current state.
void clear();
- private:
- bool mIsOutOfSync;
+ // Copies pointer-related parts of the input state to another instance.
+ void copyPointerStateTo(InputState& other) const;
+ private:
struct KeyMemento {
int32_t deviceId;
int32_t source;
@@ -756,6 +784,8 @@ private:
Vector<KeyMemento> mKeyMementos;
Vector<MotionMemento> mMotionMementos;
+
+ static bool shouldCancelEvent(int32_t eventSource, CancelationOptions options);
};
/* Manages the dispatch state associated with a single input channel. */
@@ -805,6 +835,13 @@ private:
status_t initialize();
};
+ enum DropReason {
+ DROP_REASON_NOT_DROPPED = 0,
+ DROP_REASON_POLICY = 1,
+ DROP_REASON_APP_SWITCH = 2,
+ DROP_REASON_DISABLED = 3,
+ };
+
sp<InputDispatcherPolicyInterface> mPolicy;
Mutex mLock;
@@ -824,12 +861,16 @@ private:
// Enqueues an inbound event. Returns true if mLooper->wake() should be called.
bool enqueueInboundEventLocked(EventEntry* entry);
+ // Cleans up input state when dropping an inbound event.
+ void dropInboundEventLocked(EventEntry* entry, DropReason dropReason);
+
// App switch latency optimization.
+ bool mAppSwitchSawKeyDown;
nsecs_t mAppSwitchDueTime;
- static bool isAppSwitchKey(int32_t keyCode);
+ static bool isAppSwitchKeyCode(int32_t keyCode);
+ bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry);
bool isAppSwitchPendingLocked();
- bool detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry);
void resetPendingAppSwitchLocked(bool handled);
// All registered connections mapped by receive pipe file descriptor.
@@ -851,7 +892,7 @@ private:
// Event injection and synchronization.
Condition mInjectionResultAvailableCondition;
- EventEntry* createEntryFromInjectedInputEventLocked(const InputEvent* event);
+ bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
Condition mInjectionSyncFinishedCondition;
@@ -886,7 +927,6 @@ private:
void drainInboundQueueLocked();
void releasePendingEventLocked();
void releaseInboundEventLocked(EventEntry* entry);
- bool isEventFromReliableSourceLocked(EventEntry* entry);
// Dispatch state.
bool mDispatchEnabled;
@@ -933,10 +973,10 @@ private:
nsecs_t currentTime, ConfigurationChangedEntry* entry);
bool dispatchKeyLocked(
nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
- bool dropEvent, nsecs_t* nextWakeupTime);
+ DropReason* dropReason, nsecs_t* nextWakeupTime);
bool dispatchMotionLocked(
nsecs_t currentTime, MotionEntry* entry,
- bool dropEvent, nsecs_t* nextWakeupTime);
+ DropReason* dropReason, nsecs_t* nextWakeupTime);
void dispatchEventToCurrentInputTargetsLocked(
nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
@@ -995,11 +1035,17 @@ private:
void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
void startNextDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
- void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
- bool broken);
+ void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
void drainOutboundQueueLocked(Connection* connection);
static int handleReceiveCallback(int receiveFd, int events, void* data);
+ void synthesizeCancelationEventsForAllConnectionsLocked(
+ InputState::CancelationOptions options, const char* reason);
+ void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
+ InputState::CancelationOptions options, const char* reason);
+ void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
+ InputState::CancelationOptions options, const char* reason);
+
// Splitting motion events across windows.
MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 3619189..c15e382 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -87,49 +87,12 @@ public:
ROTATION_270 = 3
};
- /* Actions returned by interceptXXX methods. */
- enum {
- // The input dispatcher should do nothing and discard the input unless other
- // flags are set.
- ACTION_NONE = 0,
-
- // The input dispatcher should dispatch the input to the application.
- ACTION_DISPATCH = 0x00000001,
- };
-
/* Gets information about the display with the specified id.
* Returns true if the display info is available, false otherwise.
*/
virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation) = 0;
- /* Intercepts a key event.
- * The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing such as updating policy flags.
- *
- * Returns a policy action constant such as ACTION_DISPATCH.
- */
- virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
- bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) = 0;
-
- /* Intercepts a switch event.
- * The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing such as updating policy flags.
- *
- * Switches are not dispatched to applications so this method should
- * usually return ACTION_NONE.
- */
- virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
- uint32_t& policyFlags) = 0;
-
- /* Intercepts a generic touch, trackball or other event.
- * The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing such as updating policy flags.
- *
- * Returns a policy action constant such as ACTION_DISPATCH.
- */
- virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags) = 0;
-
/* Determines whether to turn on some hacks we have to improve the touch interaction with a
* certain device whose screen currently is not all that good.
*/
@@ -403,8 +366,6 @@ public:
protected:
InputDevice* mDevice;
InputReaderContext* mContext;
-
- bool applyStandardPolicyActions(nsecs_t when, int32_t policyActions);
};
@@ -466,8 +427,6 @@ private:
void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
uint32_t policyFlags);
- void applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags,
- bool down, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime);
ssize_t findKeyDownLocked(int32_t scanCode);
};
@@ -525,8 +484,6 @@ private:
void initializeLocked();
void sync(nsecs_t when);
- void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
- PointerCoords* pointerCoords, nsecs_t downTime);
};
@@ -829,10 +786,6 @@ private:
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
int32_t motionEventAction);
- void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
- int32_t keyEventAction, int32_t keyEventFlags,
- int32_t keyCode, int32_t scanCode, nsecs_t downTime);
-
bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 5b226b4..57de43a 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -43,6 +43,9 @@ namespace uirenderer {
#define RAD_TO_DEG (180.0f / 3.14159265f)
#define MIN_ANGLE 0.001f
+// TODO: This should be set in properties
+#define ALPHA_THRESHOLD (0x7f / PANEL_BIT_DEPTH)
+
///////////////////////////////////////////////////////////////////////////////
// Globals
///////////////////////////////////////////////////////////////////////////////
@@ -294,7 +297,9 @@ int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
mode = SkXfermode::kSrcOver_Mode;
}
- createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags, previousFbo);
+ if (!mSnapshot->previous->invisible) {
+ createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags, previousFbo);
+ }
return count;
}
@@ -380,6 +385,14 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
if (bounds.isEmpty() || bounds.getWidth() > mMaxTextureSize ||
bounds.getHeight() > mMaxTextureSize) {
+ snapshot->invisible = true;
+ } else {
+ // TODO: Should take the mode into account
+ snapshot->invisible = snapshot->previous->invisible || alpha <= ALPHA_THRESHOLD;
+ }
+
+ // Bail out if we won't draw in this snapshot
+ if (snapshot->invisible) {
return false;
}
@@ -536,7 +549,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
}
void OpenGLRenderer::clearLayerRegions() {
- if (mLayers.size() == 0) return;
+ if (mLayers.size() == 0 || mSnapshot->invisible) return;
for (uint32_t i = 0; i < mLayers.size(); i++) {
Rect* bounds = mLayers.itemAt(i);
@@ -598,6 +611,10 @@ const Rect& OpenGLRenderer::getClipBounds() {
}
bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
+ if (mSnapshot->invisible) {
+ return true;
+ }
+
Rect r(left, top, right, bottom);
mSnapshot->transform->mapRect(r);
return !mSnapshot->clipRect->intersects(r);
@@ -703,6 +720,8 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
}
void OpenGLRenderer::drawLines(float* points, int count, const SkPaint* paint) {
+ if (mSnapshot->invisible) return;
+
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
@@ -802,6 +821,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
if (text == NULL || count == 0 || (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) {
return;
}
+ if (mSnapshot->invisible) return;
paint->setAntiAlias(true);
@@ -866,6 +886,8 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
}
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
+ if (mSnapshot->invisible) return;
+
GLuint textureUnit = 0;
glActiveTexture(gTextureUnits[textureUnit]);
@@ -985,6 +1007,7 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t
ProgramDescription description;
description.hasTexture = true;
description.hasAlpha8Texture = true;
+ const bool setColor = description.setAlpha8Color(r, g, b, a);
if (applyFilters) {
if (mShader) {
@@ -1021,7 +1044,9 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t
mModelView.loadIdentity();
}
mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
- glUniform4f(mCaches.currentProgram->color, r, g, b, a);
+ if (setColor) {
+ mCaches.currentProgram->setColor(r, g, b, a);
+ }
textureUnit++;
if (applyFilters) {
@@ -1126,6 +1151,8 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo
// Describe the required shaders
ProgramDescription description;
+ const bool setColor = description.setColor(r, g, b, a);
+
if (mShader) {
mShader->describe(description, mExtensions);
}
@@ -1152,7 +1179,7 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo
mat4 identity;
mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
}
- glUniform4f(mCaches.currentProgram->color, r, g, b, a);
+ mCaches.currentProgram->setColor(r, g, b, a);
// Setup attributes and uniforms required by the shaders
if (mShader) {
@@ -1189,6 +1216,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
ProgramDescription description;
description.hasTexture = true;
+ const bool setColor = description.setColor(alpha, alpha, alpha, alpha);
if (mColorFilter) {
mColorFilter->describe(description, mExtensions);
}
@@ -1211,7 +1239,9 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0);
// Always premultiplied
- glUniform4f(mCaches.currentProgram->color, alpha, alpha, alpha, alpha);
+ if (setColor) {
+ mCaches.currentProgram->setColor(alpha, alpha, alpha, alpha);
+ }
// Mesh
int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 2e1b9a0..25674c6 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -58,7 +58,6 @@ Program::Program(const char* vertex, const char* fragment) {
mUse = false;
position = addAttrib("position");
- color = addUniform("color");
transform = addUniform("transform");
}
@@ -124,6 +123,10 @@ void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
glUniformMatrix4fv(transform, 1, GL_FALSE, &t.data[0]);
}
+void Program::setColor(const float r, const float g, const float b, const float a) {
+ glUniform4f(getUniform("color"), r, g, b, a);
+}
+
void Program::use() {
glUseProgram(id);
mUse = true;
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 6531c74..026097c 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -77,14 +77,14 @@ public:
const mat4& transformMatrix);
/**
- * Name of the position attribute.
+ * Sets the color associated with this shader.
*/
- int position;
+ void setColor(const float r, const float g, const float b, const float a);
/**
- * Name of the color uniform.
+ * Name of the position attribute.
*/
- int color;
+ int position;
/**
* Name of the transform uniform.
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 439e6fb..1282b71 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -24,6 +24,14 @@ namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+#define MODULATE_OP_NO_MODULATE 0
+#define MODULATE_OP_MODULATE 1
+#define MODULATE_OP_MODULATE_A8 2
+
+///////////////////////////////////////////////////////////////////////////////
// Vertex shaders snippets
///////////////////////////////////////////////////////////////////////////////
@@ -50,7 +58,7 @@ const char* gVS_Header_Varyings_HasBitmap =
"varying vec2 outBitmapTexCoords;\n";
const char* gVS_Header_Varyings_HasGradient[3] = {
// Linear
- "varying float index;\n",
+ "varying vec2 linear;\n",
// Circular
"varying vec2 circular;\n",
// Sweep
@@ -62,15 +70,14 @@ const char* gVS_Main_OutTexCoords =
" outTexCoords = texCoords;\n";
const char* gVS_Main_OutGradient[3] = {
// Linear
- " index = (screenSpace * position).x;\n",
+ " linear = vec2((screenSpace * position).x, 0.5);\n",
// Circular
" circular = (screenSpace * position).xy;\n",
// Sweep
" sweep = (screenSpace * position).xy;\n"
};
const char* gVS_Main_OutBitmapTexCoords =
- " vec4 bitmapCoords = textureTransform * position;\n"
- " outBitmapTexCoords = bitmapCoords.xy * textureDimension;\n";
+ " outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_Position =
" gl_Position = transform * position;\n";
const char* gVS_Footer =
@@ -113,15 +120,55 @@ const char* gFS_Uniforms_ColorOp[4] = {
const char* gFS_Main =
"\nvoid main(void) {\n"
" lowp vec4 fragColor;\n";
+
+// Fast cases
+const char* gFS_Fast_SingleColor =
+ "\nvoid main(void) {\n"
+ " gl_FragColor = color;\n"
+ "}\n\n";
+const char* gFS_Fast_SingleTexture =
+ "\nvoid main(void) {\n"
+ " gl_FragColor = texture2D(sampler, outTexCoords);\n"
+ "}\n\n";
+const char* gFS_Fast_SingleModulateTexture =
+ "\nvoid main(void) {\n"
+ " gl_FragColor = color.a * texture2D(sampler, outTexCoords);\n"
+ "}\n\n";
+const char* gFS_Fast_SingleA8Texture =
+ "\nvoid main(void) {\n"
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, texture2D(sampler, outTexCoords).a);\n"
+ "}\n\n";
+const char* gFS_Fast_SingleModulateA8Texture =
+ "\nvoid main(void) {\n"
+ " gl_FragColor = color * texture2D(sampler, outTexCoords).a;\n"
+ "}\n\n";
+const char* gFS_Fast_SingleGradient =
+ "\nvoid main(void) {\n"
+ " gl_FragColor = texture2D(gradientSampler, linear);\n"
+ "}\n\n";
+const char* gFS_Fast_SingleModulateGradient =
+ "\nvoid main(void) {\n"
+ " gl_FragColor = color.a * texture2D(gradientSampler, linear);\n"
+ "}\n\n";
+
+// General case
const char* gFS_Main_FetchColor =
" fragColor = color;\n";
-const char* gFS_Main_FetchTexture =
- " fragColor = color * texture2D(sampler, outTexCoords);\n";
-const char* gFS_Main_FetchA8Texture =
- " fragColor = color * texture2D(sampler, outTexCoords).a;\n";
+const char* gFS_Main_FetchTexture[2] = {
+ // Don't modulate
+ " fragColor = texture2D(sampler, outTexCoords);\n",
+ // Modulate
+ " fragColor = color * texture2D(sampler, outTexCoords);\n"
+};
+const char* gFS_Main_FetchA8Texture[2] = {
+ // Don't modulate
+ " fragColor = vec4(0.0, 0.0, 0.0, texture2D(sampler, outTexCoords).a);\n",
+ // Modulate
+ " fragColor = color * texture2D(sampler, outTexCoords).a;\n"
+};
const char* gFS_Main_FetchGradient[3] = {
// Linear
- " vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n",
+ " vec4 gradientColor = texture2D(gradientSampler, linear);\n",
// Circular
" float index = length(circular);\n"
" vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n",
@@ -137,12 +184,30 @@ const char* gFS_Main_BlendShadersBG =
" fragColor = blendShaders(gradientColor, bitmapColor)";
const char* gFS_Main_BlendShadersGB =
" fragColor = blendShaders(bitmapColor, gradientColor)";
-const char* gFS_Main_BlendShaders_Modulate =
- " * fragColor.a;\n";
-const char* gFS_Main_GradientShader_Modulate =
- " fragColor = gradientColor * fragColor.a;\n";
-const char* gFS_Main_BitmapShader_Modulate =
- " fragColor = bitmapColor * fragColor.a;\n";
+const char* gFS_Main_BlendShaders_Modulate[3] = {
+ // Don't modulate
+ ";\n",
+ // Modulate
+ " * fragColor.a;\n",
+ // Modulate with alpha 8 texture
+ " * texture2D(sampler, outTexCoords).a;\n"
+};
+const char* gFS_Main_GradientShader_Modulate[3] = {
+ // Don't modulate
+ " fragColor = gradientColor;\n",
+ // Modulate
+ " fragColor = gradientColor * fragColor.a;\n",
+ // Modulate with alpha 8 texture
+ " fragColor = gradientColor * texture2D(sampler, outTexCoords).a;\n"
+ };
+const char* gFS_Main_BitmapShader_Modulate[3] = {
+ // Don't modulate
+ " fragColor = bitmapColor;\n",
+ // Modulate
+ " fragColor = bitmapColor * fragColor.a;\n",
+ // Modulate with alpha 8 texture
+ " fragColor = bitmapColor * texture2D(sampler, outTexCoords).a;\n"
+ };
const char* gFS_Main_FragColor =
" gl_FragColor = fragColor;\n";
const char* gFS_Main_FragColor_Blend =
@@ -317,7 +382,7 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
// Set the default precision
String8 shader;
- bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
+ const bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
if (blendFramebuffer) {
shader.append(gFS_Header_Extension_FramebufferFetch);
}
@@ -335,15 +400,72 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gVS_Header_Varyings_HasBitmap);
}
-
// Uniforms
- shader.append(gFS_Uniforms_Color);
+ int modulateOp = MODULATE_OP_NO_MODULATE;
+ const bool singleColor = !description.hasTexture &&
+ !description.hasGradient && !description.hasBitmap;
+
+ if (description.modulate || singleColor) {
+ shader.append(gFS_Uniforms_Color);
+ if (!singleColor) modulateOp = MODULATE_OP_MODULATE;
+ }
if (description.hasTexture) {
shader.append(gFS_Uniforms_TextureSampler);
}
if (description.hasGradient) {
shader.append(gFS_Uniforms_GradientSampler[description.gradientType]);
}
+
+ // Optimization for common cases
+ if (!blendFramebuffer) {
+ bool fast = false;
+
+ const bool noShader = !description.hasGradient && !description.hasBitmap;
+ const bool singleTexture = description.hasTexture &&
+ !description.hasAlpha8Texture && noShader;
+ const bool singleA8Texture = description.hasTexture &&
+ description.hasAlpha8Texture && noShader;
+ const bool singleGradient = !description.hasTexture &&
+ description.hasGradient && !description.hasBitmap &&
+ description.gradientType == ProgramDescription::kGradientLinear;
+
+ if (singleColor) {
+ shader.append(gFS_Fast_SingleColor);
+ fast = true;
+ } else if (singleTexture) {
+ if (!description.modulate) {
+ shader.append(gFS_Fast_SingleTexture);
+ } else {
+ shader.append(gFS_Fast_SingleModulateTexture);
+ }
+ fast = true;
+ } else if (singleA8Texture) {
+ if (!description.modulate) {
+ shader.append(gFS_Fast_SingleA8Texture);
+ } else {
+ shader.append(gFS_Fast_SingleModulateA8Texture);
+ }
+ fast = true;
+ } else if (singleGradient) {
+ if (!description.modulate) {
+ shader.append(gFS_Fast_SingleGradient);
+ } else {
+ shader.append(gFS_Fast_SingleModulateGradient);
+ }
+ fast = true;
+ }
+
+ if (fast) {
+ if (DEBUG_PROGRAM_CACHE) {
+ PROGRAM_LOGD("*** Fast case:\n");
+ PROGRAM_LOGD("*** Generated fragment shader:\n\n");
+ printLongString(shader);
+ }
+
+ return shader;
+ }
+ }
+
if (description.hasBitmap) {
shader.append(gFS_Uniforms_BitmapSampler);
}
@@ -368,12 +490,16 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
// Stores the result in fragColor directly
if (description.hasTexture) {
if (description.hasAlpha8Texture) {
- shader.append(gFS_Main_FetchA8Texture);
+ if (!description.hasGradient && !description.hasBitmap) {
+ shader.append(gFS_Main_FetchA8Texture[modulateOp]);
+ }
} else {
- shader.append(gFS_Main_FetchTexture);
+ shader.append(gFS_Main_FetchTexture[modulateOp]);
}
} else {
- shader.append(gFS_Main_FetchColor);
+ if ((!description.hasGradient && !description.hasBitmap) || description.modulate) {
+ shader.append(gFS_Main_FetchColor);
+ }
}
if (description.hasGradient) {
shader.append(gFS_Main_FetchGradient[description.gradientType]);
@@ -387,17 +513,20 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
}
// Case when we have two shaders set
if (description.hasGradient && description.hasBitmap) {
+ int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
if (description.isBitmapFirst) {
shader.append(gFS_Main_BlendShadersBG);
} else {
shader.append(gFS_Main_BlendShadersGB);
}
- shader.append(gFS_Main_BlendShaders_Modulate);
+ shader.append(gFS_Main_BlendShaders_Modulate[op]);
} else {
if (description.hasGradient) {
- shader.append(gFS_Main_GradientShader_Modulate);
+ int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
+ shader.append(gFS_Main_GradientShader_Modulate[op]);
} else if (description.hasBitmap) {
- shader.append(gFS_Main_BitmapShader_Modulate);
+ int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
+ shader.append(gFS_Main_BitmapShader_Modulate[op]);
}
}
// Apply the color op if needed
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 4fa8011..ec9851e 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -44,6 +44,11 @@ namespace uirenderer {
#define PROGRAM_LOGD(...)
#endif
+// TODO: This should be set in properties
+#define PANEL_BIT_DEPTH 20
+#define COLOR_COMPONENT_THRESHOLD (1.0f - (0.5f / PANEL_BIT_DEPTH))
+#define COLOR_COMPONENT_INV_THRESHOLD (0.5f / PANEL_BIT_DEPTH)
+
#define PROGRAM_KEY_TEXTURE 0x1
#define PROGRAM_KEY_A8_TEXTURE 0x2
#define PROGRAM_KEY_BITMAP 0x4
@@ -68,6 +73,7 @@ namespace uirenderer {
#define PROGRAM_BITMAP_WRAPT_SHIFT 11
#define PROGRAM_GRADIENT_TYPE_SHIFT 33
+#define PROGRAM_MODULATE 35
///////////////////////////////////////////////////////////////////////////////
// Types
@@ -99,7 +105,7 @@ struct ProgramDescription {
};
ProgramDescription():
- hasTexture(false), hasAlpha8Texture(false),
+ hasTexture(false), hasAlpha8Texture(false), modulate(false),
hasBitmap(false), isBitmapNpot(false), hasGradient(false),
gradientType(kGradientLinear),
shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
@@ -112,6 +118,9 @@ struct ProgramDescription {
bool hasTexture;
bool hasAlpha8Texture;
+ // Modulate, this should only be set when setColor() return true
+ bool modulate;
+
// Shaders
bool hasBitmap;
bool isBitmapNpot;
@@ -134,18 +143,31 @@ struct ProgramDescription {
SkXfermode::Mode framebufferMode;
bool swapSrcDst;
- inline uint32_t getEnumForWrap(GLenum wrap) const {
- switch (wrap) {
- case GL_CLAMP_TO_EDGE:
- return 0;
- case GL_REPEAT:
- return 1;
- case GL_MIRRORED_REPEAT:
- return 2;
- }
- return 0;
+ /**
+ * Indicates, for a given color, whether color modulation is required in
+ * the fragment shader. When this method returns true, the program should
+ * be provided with a modulation color.
+ */
+ bool setColor(const float r, const float g, const float b, const float a) {
+ modulate = a < COLOR_COMPONENT_THRESHOLD || r < COLOR_COMPONENT_THRESHOLD ||
+ g < COLOR_COMPONENT_THRESHOLD || b < COLOR_COMPONENT_THRESHOLD;
+ return modulate;
+ }
+
+ /**
+ * Indicates, for a given color, whether color modulation is required in
+ * the fragment shader. When this method returns true, the program should
+ * be provided with a modulation color.
+ */
+ bool setAlpha8Color(const float r, const float g, const float b, const float a) {
+ modulate = a < COLOR_COMPONENT_THRESHOLD || r > COLOR_COMPONENT_INV_THRESHOLD ||
+ g > COLOR_COMPONENT_INV_THRESHOLD || b > COLOR_COMPONENT_INV_THRESHOLD;
+ return modulate;
}
+ /**
+ * Computes the unique key identifying this program.
+ */
programid key() const {
programid key = 0;
if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
@@ -180,14 +202,32 @@ struct ProgramDescription {
}
key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
+ if (modulate) key |= programid(0x1) << PROGRAM_MODULATE;
return key;
}
+ /**
+ * Logs the specified message followed by the key identifying this program.
+ */
void log(const char* message) const {
programid k = key();
PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32),
uint32_t(k & 0xffffffff));
}
+
+private:
+ inline uint32_t getEnumForWrap(GLenum wrap) const {
+ switch (wrap) {
+ case GL_CLAMP_TO_EDGE:
+ return 0;
+ case GL_REPEAT:
+ return 1;
+ case GL_MIRRORED_REPEAT:
+ return 2;
+ }
+ return 0;
+ }
+
}; // struct ProgramDescription
/**
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 3d74b4c..35cdf6f 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -43,7 +43,7 @@ namespace uirenderer {
*/
class Snapshot: public LightRefBase<Snapshot> {
public:
- Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0) {
+ Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false) {
transform = &mTransformRoot;
clipRect = &mClipRectRoot;
}
@@ -53,8 +53,8 @@ public:
* the previous snapshot.
*/
Snapshot(const sp<Snapshot>& s, int saveFlags):
- flags(0), previous(s), layer(NULL),
- fbo(s->fbo), viewport(s->viewport), height(s->height) {
+ flags(0), previous(s), layer(NULL), fbo(s->fbo),
+ invisible(s->invisible), viewport(s->viewport), height(s->height) {
if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
mTransformRoot.load(*s->transform);
transform = &mTransformRoot;
@@ -212,6 +212,12 @@ public:
GLuint fbo;
/**
+ * Indicates that this snapshot is invisible and nothing should be drawn
+ * inside it.
+ */
+ bool invisible;
+
+ /**
* Current viewport.
*/
Rect viewport;
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
index 32b55d9..da995da 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
@@ -58,18 +58,30 @@ public class UT_primitives extends UnitTest {
}
s.set_intTest(-64);
- /*long pL = s.get_longTest();
+ long pL = s.get_longTest();
if (pL != 17179869184l) {
return false;
}
- s.set_longTest(17179869185l);*/
+ s.set_longTest(17179869185l);
+
+ long puL = s.get_ulongTest();
+ if (puL != 4611686018427387904L) {
+ return false;
+ }
+ s.set_ulongTest(4611686018427387903L);
+
long pLL = s.get_longlongTest();
if (pLL != 68719476736L) {
return false;
}
s.set_longlongTest(68719476735L);
- //s.set_longlongTest(0);
+
+ long pu64 = s.get_uint64_tTest();
+ if (pu64 != 117179869184l) {
+ return false;
+ }
+ s.set_uint64_tTest(117179869185l);
return true;
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs
index 2db82da..351a8a5 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs
@@ -14,7 +14,9 @@ long long longlongTest = 68719476736l; // 1 << 36
uchar ucharTest = 8;
ushort ushortTest = 16;
uint uintTest = 32;
+ulong ulongTest = 4611686018427387904L;
int64_t int64_tTest = -17179869184l; // - 1 << 34
+uint64_t uint64_tTest = 117179869184l;
static bool test_primitive_types(uint32_t index) {
bool failed = false;
@@ -25,13 +27,15 @@ static bool test_primitive_types(uint32_t index) {
_RS_ASSERT(charTest == -16);
_RS_ASSERT(shortTest == -32);
_RS_ASSERT(intTest == -64);
- _RS_ASSERT(longTest == 17179869184l);
+ _RS_ASSERT(longTest == 17179869185l);
_RS_ASSERT(longlongTest == 68719476735l);
_RS_ASSERT(ucharTest == 8);
_RS_ASSERT(ushortTest == 16);
_RS_ASSERT(uintTest == 32);
+ _RS_ASSERT(ulongTest == 4611686018427387903L);
_RS_ASSERT(int64_tTest == -17179869184l);
+ _RS_ASSERT(uint64_tTest == 117179869185l);
float time = end(index);
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 75b2294..52e488a 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -95,16 +95,19 @@ static bool validateKeyEvent(int32_t action) {
return true;
}
-static bool isValidMotionAction(int32_t action) {
+static bool isValidMotionAction(int32_t action, size_t pointerCount) {
switch (action & AMOTION_EVENT_ACTION_MASK) {
case AMOTION_EVENT_ACTION_DOWN:
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_CANCEL:
case AMOTION_EVENT_ACTION_MOVE:
- case AMOTION_EVENT_ACTION_POINTER_DOWN:
- case AMOTION_EVENT_ACTION_POINTER_UP:
case AMOTION_EVENT_ACTION_OUTSIDE:
return true;
+ case AMOTION_EVENT_ACTION_POINTER_DOWN:
+ case AMOTION_EVENT_ACTION_POINTER_UP: {
+ int32_t index = getMotionEventActionPointerIndex(action);
+ return index >= 0 && size_t(index) < pointerCount;
+ }
default:
return false;
}
@@ -112,7 +115,7 @@ static bool isValidMotionAction(int32_t action) {
static bool validateMotionEvent(int32_t action, size_t pointerCount,
const int32_t* pointerIds) {
- if (! isValidMotionAction(action)) {
+ if (! isValidMotionAction(action, pointerCount)) {
LOGE("Motion event has invalid action code 0x%x", action);
return false;
}
@@ -235,16 +238,6 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
resetKeyRepeatLocked();
}
- // If dispatching is disabled, drop all events in the queue.
- if (! mDispatchEnabled) {
- if (mPendingEvent || ! mInboundQueue.isEmpty()) {
- LOGI("Dropping pending events because input dispatch is disabled.");
- releasePendingEventLocked();
- drainInboundQueueLocked();
- }
- return;
- }
-
// If dispatching is frozen, do not process timeouts or try to deliver any new events.
if (mDispatchFrozen) {
#if DEBUG_FOCUS
@@ -294,7 +287,11 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
// samples may be appended to this event by the time the throttling timeout
// expires.
// TODO Make this smarter and consider throttling per device independently.
- if (entry->type == EventEntry::TYPE_MOTION) {
+ if (entry->type == EventEntry::TYPE_MOTION
+ && !isAppSwitchDue
+ && mDispatchEnabled
+ && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
+ && !entry->isInjected()) {
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
int32_t deviceId = motionEntry->deviceId;
uint32_t source = motionEntry->source;
@@ -347,39 +344,43 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
// Now we have an event to dispatch.
assert(mPendingEvent != NULL);
bool done = false;
+ DropReason dropReason = DROP_REASON_NOT_DROPPED;
+ if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
+ dropReason = DROP_REASON_POLICY;
+ } else if (!mDispatchEnabled) {
+ dropReason = DROP_REASON_DISABLED;
+ }
switch (mPendingEvent->type) {
case EventEntry::TYPE_CONFIGURATION_CHANGED: {
ConfigurationChangedEntry* typedEntry =
static_cast<ConfigurationChangedEntry*>(mPendingEvent);
done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
+ dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
break;
}
case EventEntry::TYPE_KEY: {
KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
- bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
- bool dropEvent = isAppSwitchDue && ! appSwitchKey;
- done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
- nextWakeupTime);
- if (done) {
- if (dropEvent) {
- LOGI("Dropped key because of pending overdue app switch.");
- } else if (appSwitchKey) {
+ if (isAppSwitchDue) {
+ if (isAppSwitchKeyEventLocked(typedEntry)) {
resetPendingAppSwitchLocked(true);
+ isAppSwitchDue = false;
+ } else if (dropReason == DROP_REASON_NOT_DROPPED) {
+ dropReason = DROP_REASON_APP_SWITCH;
}
}
+ done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
+ &dropReason, nextWakeupTime);
break;
}
case EventEntry::TYPE_MOTION: {
MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
- bool dropEvent = isAppSwitchDue;
- done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
- if (done) {
- if (dropEvent) {
- LOGI("Dropped motion because of pending overdue app switch.");
- }
+ if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
+ dropReason = DROP_REASON_APP_SWITCH;
}
+ done = dispatchMotionLocked(currentTime, typedEntry,
+ &dropReason, nextWakeupTime);
break;
}
@@ -389,6 +390,10 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
}
if (done) {
+ if (dropReason != DROP_REASON_NOT_DROPPED) {
+ dropInboundEventLocked(mPendingEvent, dropReason);
+ }
+
releasePendingEventLocked();
*nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
}
@@ -399,34 +404,84 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
mInboundQueue.enqueueAtTail(entry);
switch (entry->type) {
- case EventEntry::TYPE_KEY:
- needWake |= detectPendingAppSwitchLocked(static_cast<KeyEntry*>(entry));
+ case EventEntry::TYPE_KEY: {
+ KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
+ if (isAppSwitchKeyEventLocked(keyEntry)) {
+ if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
+ mAppSwitchSawKeyDown = true;
+ } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
+ if (mAppSwitchSawKeyDown) {
+#if DEBUG_APP_SWITCH
+ LOGD("App switch is pending!");
+#endif
+ mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
+ mAppSwitchSawKeyDown = false;
+ needWake = true;
+ }
+ }
+ }
break;
}
+ }
return needWake;
}
-bool InputDispatcher::isAppSwitchKey(int32_t keyCode) {
+void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
+ const char* reason;
+ switch (dropReason) {
+ case DROP_REASON_POLICY:
+#if DEBUG_INBOUND_EVENT_DETAILS
+ LOGD("Dropped event because policy requested that it not be delivered to the application.");
+#endif
+ reason = "inbound event was dropped because the policy requested that it not be "
+ "delivered to the application";
+ break;
+ case DROP_REASON_DISABLED:
+ LOGI("Dropped event because input dispatch is disabled.");
+ reason = "inbound event was dropped because input dispatch is disabled";
+ break;
+ case DROP_REASON_APP_SWITCH:
+ LOGI("Dropped event because of pending overdue app switch.");
+ reason = "inbound event was dropped because of pending overdue app switch";
+ break;
+ default:
+ assert(false);
+ return;
+ }
+
+ switch (entry->type) {
+ case EventEntry::TYPE_KEY:
+ synthesizeCancelationEventsForAllConnectionsLocked(
+ InputState::CANCEL_NON_POINTER_EVENTS, reason);
+ break;
+ case EventEntry::TYPE_MOTION: {
+ MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+ if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+ synthesizeCancelationEventsForAllConnectionsLocked(
+ InputState::CANCEL_POINTER_EVENTS, reason);
+ } else {
+ synthesizeCancelationEventsForAllConnectionsLocked(
+ InputState::CANCEL_NON_POINTER_EVENTS, reason);
+ }
+ break;
+ }
+ }
+}
+
+bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
}
-bool InputDispatcher::isAppSwitchPendingLocked() {
- return mAppSwitchDueTime != LONG_LONG_MAX;
+bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
+ return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
+ && isAppSwitchKeyCode(keyEntry->keyCode)
+ && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
+ && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
}
-bool InputDispatcher::detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry) {
- if (inboundKeyEntry->action == AKEY_EVENT_ACTION_UP
- && ! (inboundKeyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
- && isAppSwitchKey(inboundKeyEntry->keyCode)
- && isEventFromReliableSourceLocked(inboundKeyEntry)) {
-#if DEBUG_APP_SWITCH
- LOGD("App switch is pending!");
-#endif
- mAppSwitchDueTime = inboundKeyEntry->eventTime + APP_SWITCH_TIMEOUT;
- return true; // need wake
- }
- return false;
+bool InputDispatcher::isAppSwitchPendingLocked() {
+ return mAppSwitchDueTime != LONG_LONG_MAX;
}
void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
@@ -489,14 +544,6 @@ void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
mAllocator.releaseEventEntry(entry);
}
-bool InputDispatcher::isEventFromReliableSourceLocked(EventEntry* entry) {
- InjectionState* injectionState = entry->injectionState;
- return ! injectionState
- || injectionState->injectorUid == 0
- || mPolicy->checkInjectEventsPermissionNonReentrant(
- injectionState->injectorPid, injectionState->injectorUid);
-}
-
void InputDispatcher::resetKeyRepeatLocked() {
if (mKeyRepeatState.lastKeyEntry) {
mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
@@ -509,7 +556,8 @@ InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
// Reuse the repeated key entry if it is otherwise unreferenced.
- uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
+ uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
+ | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
if (entry->refCount == 1) {
mAllocator.recycleKeyEntry(entry);
entry->eventTime = currentTime;
@@ -558,19 +606,13 @@ bool InputDispatcher::dispatchConfigurationChangedLocked(
bool InputDispatcher::dispatchKeyLocked(
nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
- bool dropEvent, nsecs_t* nextWakeupTime) {
+ DropReason* dropReason, nsecs_t* nextWakeupTime) {
// Give the policy a chance to intercept the key.
if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
- bool trusted;
- if (! dropEvent && mFocusedWindow) {
- trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
- } else {
- trusted = isEventFromReliableSourceLocked(entry);
- }
- if (trusted) {
+ if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
- if (! dropEvent && mFocusedWindow) {
+ if (mFocusedWindow) {
commandEntry->inputChannel = mFocusedWindow->inputChannel;
}
commandEntry->keyEntry = entry;
@@ -580,13 +622,16 @@ bool InputDispatcher::dispatchKeyLocked(
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
}
} else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
+ if (*dropReason == DROP_REASON_NOT_DROPPED) {
+ *dropReason = DROP_REASON_POLICY;
+ }
resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
return true;
}
// Clean up if dropping the event.
- if (dropEvent) {
+ if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
return true;
@@ -598,7 +643,8 @@ bool InputDispatcher::dispatchKeyLocked(
if (entry->repeatCount == 0
&& entry->action == AKEY_EVENT_ACTION_DOWN
- && ! entry->isInjected()) {
+ && (entry->policyFlags & POLICY_FLAG_TRUSTED)
+ && !entry->isInjected()) {
if (mKeyRepeatState.lastKeyEntry
&& mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
// We have seen two identical key downs in a row which indicates that the device
@@ -663,9 +709,9 @@ void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyE
}
bool InputDispatcher::dispatchMotionLocked(
- nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
+ nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
// Clean up if dropping the event.
- if (dropEvent) {
+ if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
return true;
@@ -793,9 +839,11 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi
prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
resumeWithAppendedMotionSample);
} else {
- LOGW("Framework requested delivery of an input event to channel '%s' but it "
- "is not registered with the input dispatcher.",
+#if DEBUG_FOCUS
+ LOGD("Dropping event delivery to target with channel '%s' because it "
+ "is no longer registered with the input dispatcher.",
inputTarget.inputChannel->getName().string());
+#endif
}
}
}
@@ -876,7 +924,9 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout
ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
if (connectionIndex >= 0) {
sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
- connection->inputState.setOutOfSync();
+ synthesizeCancelationEventsForConnectionLocked(
+ connection, InputState::CANCEL_ALL_EVENTS,
+ "application not responding");
}
}
}
@@ -1236,7 +1286,9 @@ Failed:
} else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
// First pointer went down.
if (mTouchState.down) {
- LOGW("Pointer down received while already down.");
+#if DEBUG_FOCUS
+ LOGD("Pointer down received while already down.");
+#endif
}
} else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
// One pointer went up.
@@ -1307,23 +1359,19 @@ void InputDispatcher::addMonitoringTargetsLocked() {
bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
const InjectionState* injectionState) {
if (injectionState
- && injectionState->injectorUid > 0
- && (window == NULL || window->ownerUid != injectionState->injectorUid)) {
- bool result = mPolicy->checkInjectEventsPermissionNonReentrant(
- injectionState->injectorPid, injectionState->injectorUid);
- if (! result) {
- if (window) {
- LOGW("Permission denied: injecting event from pid %d uid %d to window "
- "with input channel %s owned by uid %d",
- injectionState->injectorPid, injectionState->injectorUid,
- window->inputChannel->getName().string(),
- window->ownerUid);
- } else {
- LOGW("Permission denied: injecting event from pid %d uid %d",
- injectionState->injectorPid, injectionState->injectorUid);
- }
- return false;
+ && (window == NULL || window->ownerUid != injectionState->injectorUid)
+ && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
+ if (window) {
+ LOGW("Permission denied: injecting event from pid %d uid %d to window "
+ "with input channel %s owned by uid %d",
+ injectionState->injectorPid, injectionState->injectorUid,
+ window->inputChannel->getName().string(),
+ window->ownerUid);
+ } else {
+ LOGW("Permission denied: injecting event from pid %d uid %d",
+ injectionState->injectorPid, injectionState->injectorUid);
}
+ return false;
}
return true;
}
@@ -1408,8 +1456,10 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
// Skip this event if the connection status is not normal.
// We don't want to enqueue additional outbound events if the connection is broken.
if (connection->status != Connection::STATUS_NORMAL) {
- LOGW("channel '%s' ~ Dropping event because the channel status is %s",
+#if DEBUG_DISPATCH_CYCLE
+ LOGD("channel '%s' ~ Dropping event because the channel status is %s",
connection->getInputChannelName(), connection->getStatusLabel());
+#endif
return;
}
@@ -1508,40 +1558,6 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
}
}
- // Bring the input state back in line with reality in case it drifted off during an ANR.
- if (connection->inputState.isOutOfSync()) {
- mTempCancelationEvents.clear();
- connection->inputState.synthesizeCancelationEvents(& mAllocator, mTempCancelationEvents);
- connection->inputState.resetOutOfSync();
-
- if (! mTempCancelationEvents.isEmpty()) {
- LOGI("channel '%s' ~ Generated %d cancelation events to bring channel back in sync "
- "with reality.",
- connection->getInputChannelName(), mTempCancelationEvents.size());
-
- for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
- EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
- switch (cancelationEventEntry->type) {
- case EventEntry::TYPE_KEY:
- logOutboundKeyDetailsLocked(" ",
- static_cast<KeyEntry*>(cancelationEventEntry));
- break;
- case EventEntry::TYPE_MOTION:
- logOutboundMotionDetailsLocked(" ",
- static_cast<MotionEntry*>(cancelationEventEntry));
- break;
- }
-
- DispatchEntry* cancelationDispatchEntry =
- mAllocator.obtainDispatchEntry(cancelationEventEntry,
- 0, inputTarget->xOffset, inputTarget->yOffset); // increments ref
- connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
-
- mAllocator.releaseEventEntry(cancelationEventEntry);
- }
- }
- }
-
// This is a new event.
// Enqueue a new dispatch entry onto the outbound queue for this connection.
DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
@@ -1635,7 +1651,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
if (status) {
LOGE("channel '%s' ~ Could not publish key event, "
"status=%d", connection->getInputChannelName(), status);
- abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ abortBrokenDispatchCycleLocked(currentTime, connection);
return;
}
break;
@@ -1685,7 +1701,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
if (status) {
LOGE("channel '%s' ~ Could not publish motion event, "
"status=%d", connection->getInputChannelName(), status);
- abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ abortBrokenDispatchCycleLocked(currentTime, connection);
return;
}
@@ -1706,7 +1722,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
LOGE("channel '%s' ~ Could not append motion sample "
"for a reason other than out of memory, status=%d",
connection->getInputChannelName(), status);
- abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ abortBrokenDispatchCycleLocked(currentTime, connection);
return;
}
}
@@ -1727,7 +1743,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
if (status) {
LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
connection->getInputChannelName(), status);
- abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ abortBrokenDispatchCycleLocked(currentTime, connection);
return;
}
@@ -1764,7 +1780,7 @@ void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
if (status) {
LOGE("channel '%s' ~ Could not reset publisher, status=%d",
connection->getInputChannelName(), status);
- abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ abortBrokenDispatchCycleLocked(currentTime, connection);
return;
}
@@ -1806,28 +1822,23 @@ void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
deactivateConnectionLocked(connection.get());
}
-void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
- const sp<Connection>& connection, bool broken) {
+void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
+ const sp<Connection>& connection) {
#if DEBUG_DISPATCH_CYCLE
- LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
+ LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
connection->getInputChannelName(), toString(broken));
#endif
- // Input state will no longer be realistic.
- connection->inputState.setOutOfSync();
-
// Clear the outbound queue.
drainOutboundQueueLocked(connection.get());
- // Handle the case where the connection appears to be unrecoverably broken.
+ // The connection appears to be unrecoverably broken.
// Ignore already broken or zombie connections.
- if (broken) {
- if (connection->status == Connection::STATUS_NORMAL) {
- connection->status = Connection::STATUS_BROKEN;
+ if (connection->status == Connection::STATUS_NORMAL) {
+ connection->status = Connection::STATUS_BROKEN;
- // Notify other system components.
- onDispatchCycleBrokenLocked(currentTime, connection);
- }
+ // Notify other system components.
+ onDispatchCycleBrokenLocked(currentTime, connection);
}
}
@@ -1862,7 +1873,7 @@ int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data
if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
"events=0x%x", connection->getInputChannelName(), events);
- d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ d->abortBrokenDispatchCycleLocked(currentTime, connection);
d->runCommandsLockedInterruptible();
return 0; // remove the callback
}
@@ -1877,7 +1888,7 @@ int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data
if (status) {
LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
connection->getInputChannelName(), status);
- d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ d->abortBrokenDispatchCycleLocked(currentTime, connection);
d->runCommandsLockedInterruptible();
return 0; // remove the callback
}
@@ -1888,6 +1899,77 @@ int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data
} // release lock
}
+void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
+ InputState::CancelationOptions options, const char* reason) {
+ for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
+ synthesizeCancelationEventsForConnectionLocked(
+ mConnectionsByReceiveFd.valueAt(i), options, reason);
+ }
+}
+
+void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
+ const sp<InputChannel>& channel, InputState::CancelationOptions options,
+ const char* reason) {
+ ssize_t index = getConnectionIndexLocked(channel);
+ if (index >= 0) {
+ synthesizeCancelationEventsForConnectionLocked(
+ mConnectionsByReceiveFd.valueAt(index), options, reason);
+ }
+}
+
+void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
+ const sp<Connection>& connection, InputState::CancelationOptions options,
+ const char* reason) {
+ nsecs_t currentTime = now();
+
+ mTempCancelationEvents.clear();
+ connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
+ mTempCancelationEvents, options);
+
+ if (! mTempCancelationEvents.isEmpty()
+ && connection->status != Connection::STATUS_BROKEN) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+ LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
+ "with reality: %s, options=%d.",
+ connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
+#endif
+ for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
+ EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
+ switch (cancelationEventEntry->type) {
+ case EventEntry::TYPE_KEY:
+ logOutboundKeyDetailsLocked("cancel - ",
+ static_cast<KeyEntry*>(cancelationEventEntry));
+ break;
+ case EventEntry::TYPE_MOTION:
+ logOutboundMotionDetailsLocked("cancel - ",
+ static_cast<MotionEntry*>(cancelationEventEntry));
+ break;
+ }
+
+ int32_t xOffset, yOffset;
+ const InputWindow* window = getWindowLocked(connection->inputChannel);
+ if (window) {
+ xOffset = -window->frameLeft;
+ yOffset = -window->frameTop;
+ } else {
+ xOffset = 0;
+ yOffset = 0;
+ }
+
+ DispatchEntry* cancelationDispatchEntry =
+ mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
+ 0, xOffset, yOffset);
+ connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
+
+ mAllocator.releaseEventEntry(cancelationEventEntry);
+ }
+
+ if (!connection->outboundQueue.headSentinel.next->inProgress) {
+ startDispatchCycleLocked(currentTime, connection);
+ }
+ }
+}
+
InputDispatcher::MotionEntry*
InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
assert(pointerIds.value != 0);
@@ -1999,6 +2081,10 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t sou
return;
}
+ policyFlags |= POLICY_FLAG_TRUSTED;
+ mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
+ keyCode, scanCode, /*byref*/ policyFlags);
+
bool needWake;
{ // acquire lock
AutoMutex _l(mLock);
@@ -2041,6 +2127,9 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t
return;
}
+ policyFlags |= POLICY_FLAG_TRUSTED;
+ mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
+
bool needWake;
{ // acquire lock
AutoMutex _l(mLock);
@@ -2165,6 +2254,17 @@ NoBatchingOrStreaming:;
}
}
+void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+ uint32_t policyFlags) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+ LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
+ switchCode, switchValue, policyFlags);
+#endif
+
+ policyFlags |= POLICY_FLAG_TRUSTED;
+ mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
+}
+
int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
#if DEBUG_INBOUND_EVENT_DETAILS
@@ -2175,26 +2275,81 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
- InjectionState* injectionState;
- bool needWake;
- { // acquire lock
- AutoMutex _l(mLock);
+ uint32_t policyFlags = POLICY_FLAG_INJECTED;
+ if (hasInjectionPermission(injectorPid, injectorUid)) {
+ policyFlags |= POLICY_FLAG_TRUSTED;
+ }
- EventEntry* injectedEntry = createEntryFromInjectedInputEventLocked(event);
- if (! injectedEntry) {
+ EventEntry* injectedEntry;
+ switch (event->getType()) {
+ case AINPUT_EVENT_TYPE_KEY: {
+ const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
+ int32_t action = keyEvent->getAction();
+ if (! validateKeyEvent(action)) {
return INPUT_EVENT_INJECTION_FAILED;
}
- injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
- if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
- injectionState->injectionIsAsync = true;
+ nsecs_t eventTime = keyEvent->getEventTime();
+ int32_t deviceId = keyEvent->getDeviceId();
+ int32_t flags = keyEvent->getFlags();
+ int32_t keyCode = keyEvent->getKeyCode();
+ int32_t scanCode = keyEvent->getScanCode();
+ mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
+ keyCode, scanCode, /*byref*/ policyFlags);
+
+ mLock.lock();
+ injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
+ policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
+ keyEvent->getRepeatCount(), keyEvent->getDownTime());
+ break;
+ }
+
+ case AINPUT_EVENT_TYPE_MOTION: {
+ const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
+ int32_t action = motionEvent->getAction();
+ size_t pointerCount = motionEvent->getPointerCount();
+ const int32_t* pointerIds = motionEvent->getPointerIds();
+ if (! validateMotionEvent(action, pointerCount, pointerIds)) {
+ return INPUT_EVENT_INJECTION_FAILED;
}
- injectionState->refCount += 1;
- injectedEntry->injectionState = injectionState;
+ nsecs_t eventTime = motionEvent->getEventTime();
+ mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
- needWake = enqueueInboundEventLocked(injectedEntry);
- } // release lock
+ mLock.lock();
+ const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
+ const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
+ MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
+ motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+ action, motionEvent->getFlags(),
+ motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
+ motionEvent->getXPrecision(), motionEvent->getYPrecision(),
+ motionEvent->getDownTime(), uint32_t(pointerCount),
+ pointerIds, samplePointerCoords);
+ for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
+ sampleEventTimes += 1;
+ samplePointerCoords += pointerCount;
+ mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
+ }
+ injectedEntry = motionEntry;
+ break;
+ }
+
+ default:
+ LOGW("Cannot inject event of type %d", event->getType());
+ return INPUT_EVENT_INJECTION_FAILED;
+ }
+
+ InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
+ if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+ injectionState->injectionIsAsync = true;
+ }
+
+ injectionState->refCount += 1;
+ injectedEntry->injectionState = injectionState;
+
+ bool needWake = enqueueInboundEventLocked(injectedEntry);
+ mLock.unlock();
if (needWake) {
mLooper->wake();
@@ -2260,6 +2415,11 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
return injectionResult;
}
+bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
+ return injectorUid == 0
+ || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
+}
+
void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
InjectionState* injectionState = entry->injectionState;
if (injectionState) {
@@ -2310,59 +2470,6 @@ void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* ent
}
}
-InputDispatcher::EventEntry* InputDispatcher::createEntryFromInjectedInputEventLocked(
- const InputEvent* event) {
- switch (event->getType()) {
- case AINPUT_EVENT_TYPE_KEY: {
- const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
- if (! validateKeyEvent(keyEvent->getAction())) {
- return NULL;
- }
-
- uint32_t policyFlags = POLICY_FLAG_INJECTED;
-
- KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
- keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
- keyEvent->getAction(), keyEvent->getFlags(),
- keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
- keyEvent->getRepeatCount(), keyEvent->getDownTime());
- return keyEntry;
- }
-
- case AINPUT_EVENT_TYPE_MOTION: {
- const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
- if (! validateMotionEvent(motionEvent->getAction(),
- motionEvent->getPointerCount(), motionEvent->getPointerIds())) {
- return NULL;
- }
-
- uint32_t policyFlags = POLICY_FLAG_INJECTED;
-
- const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
- const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
- size_t pointerCount = motionEvent->getPointerCount();
-
- MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
- motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
- motionEvent->getAction(), motionEvent->getFlags(),
- motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
- motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(), uint32_t(pointerCount),
- motionEvent->getPointerIds(), samplePointerCoords);
- for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
- sampleEventTimes += 1;
- samplePointerCoords += pointerCount;
- mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
- }
- return motionEntry;
- }
-
- default:
- assert(false);
- return NULL;
- }
-}
-
const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
for (size_t i = 0; i < mWindows.size(); i++) {
const InputWindow* window = & mWindows[i];
@@ -2381,7 +2488,12 @@ void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
AutoMutex _l(mLock);
// Clear old window pointers.
- mFocusedWindow = NULL;
+ sp<InputChannel> oldFocusedWindowChannel;
+ if (mFocusedWindow) {
+ oldFocusedWindowChannel = mFocusedWindow->inputChannel;
+ mFocusedWindow = NULL;
+ }
+
mWindows.clear();
// Loop over new windows and rebuild the necessary window pointers for
@@ -2397,6 +2509,24 @@ void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
}
}
+ if (oldFocusedWindowChannel != NULL) {
+ if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
+#if DEBUG_FOCUS
+ LOGD("Focus left window: %s",
+ oldFocusedWindowChannel->getName().string());
+#endif
+ synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
+ InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
+ oldFocusedWindowChannel.clear();
+ }
+ }
+ if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
+#if DEBUG_FOCUS
+ LOGD("Focus entered window: %s",
+ mFocusedWindow->inputChannel->getName().string());
+#endif
+ }
+
for (size_t i = 0; i < mTouchState.windows.size(); ) {
TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
const InputWindow* window = getWindowLocked(touchedWindow.channel);
@@ -2404,12 +2534,17 @@ void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
touchedWindow.window = window;
i += 1;
} else {
+#if DEBUG_FOCUS
+ LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
+#endif
mTouchState.windows.removeAt(i);
+ synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
+ InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
}
}
#if DEBUG_FOCUS
- logDispatchStateLocked();
+ //logDispatchStateLocked();
#endif
} // release lock
@@ -2432,7 +2567,7 @@ void InputDispatcher::setFocusedApplication(const InputApplication* inputApplica
}
#if DEBUG_FOCUS
- logDispatchStateLocked();
+ //logDispatchStateLocked();
#endif
} // release lock
@@ -2469,7 +2604,7 @@ void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
}
#if DEBUG_FOCUS
- logDispatchStateLocked();
+ //logDispatchStateLocked();
#endif
} // release lock
@@ -2533,6 +2668,18 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
return false;
}
+ ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
+ ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
+ if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
+ sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
+ sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
+
+ fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
+ synthesizeCancelationEventsForConnectionLocked(fromConnection,
+ InputState::CANCEL_POINTER_EVENTS,
+ "transferring touch focus from this window to another window");
+ }
+
#if DEBUG_FOCUS
logDispatchStateLocked();
#endif
@@ -2635,11 +2782,10 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
for (size_t i = 0; i < mActiveConnections.size(); i++) {
const Connection* connection = mActiveConnections[i];
dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
- "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n",
+ "inputState.isNeutral=%s\n",
i, connection->getInputChannelName(), connection->getStatusLabel(),
connection->outboundQueue.count(),
- toString(connection->inputState.isNeutral()),
- toString(connection->inputState.isOutOfSync()));
+ toString(connection->inputState.isNeutral()));
}
} else {
dump.append(INDENT "ActiveConnections: <none>\n");
@@ -2720,7 +2866,7 @@ status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputCh
mLooper->removeFd(inputChannel->getReceivePipeFd());
nsecs_t currentTime = now();
- abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+ abortBrokenDispatchCycleLocked(currentTime, connection);
runCommandsLockedInterruptible();
} // release lock
@@ -2901,11 +3047,12 @@ InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t in
}
void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
- nsecs_t eventTime) {
+ nsecs_t eventTime, uint32_t policyFlags) {
entry->type = type;
entry->refCount = 1;
entry->dispatchInProgress = false;
entry->eventTime = eventTime;
+ entry->policyFlags = policyFlags;
entry->injectionState = NULL;
}
@@ -2919,7 +3066,7 @@ void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* ent
InputDispatcher::ConfigurationChangedEntry*
InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
+ initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
return entry;
}
@@ -2928,11 +3075,10 @@ InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t ev
int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
int32_t repeatCount, nsecs_t downTime) {
KeyEntry* entry = mKeyEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
+ initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
entry->deviceId = deviceId;
entry->source = source;
- entry->policyFlags = policyFlags;
entry->action = action;
entry->flags = flags;
entry->keyCode = keyCode;
@@ -2951,12 +3097,11 @@ InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsec
nsecs_t downTime, uint32_t pointerCount,
const int32_t* pointerIds, const PointerCoords* pointerCoords) {
MotionEntry* entry = mMotionEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
+ initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
entry->eventTime = eventTime;
entry->deviceId = deviceId;
entry->source = source;
- entry->policyFlags = policyFlags;
entry->action = action;
entry->flags = flags;
entry->metaState = metaState;
@@ -3103,8 +3248,7 @@ uint32_t InputDispatcher::MotionEntry::countSamples() const {
// --- InputDispatcher::InputState ---
-InputDispatcher::InputState::InputState() :
- mIsOutOfSync(false) {
+InputDispatcher::InputState::InputState() {
}
InputDispatcher::InputState::~InputState() {
@@ -3114,20 +3258,6 @@ bool InputDispatcher::InputState::isNeutral() const {
return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
}
-bool InputDispatcher::InputState::isOutOfSync() const {
- return mIsOutOfSync;
-}
-
-void InputDispatcher::InputState::setOutOfSync() {
- if (! isNeutral()) {
- mIsOutOfSync = true;
- }
-}
-
-void InputDispatcher::InputState::resetOutOfSync() {
- mIsOutOfSync = false;
-}
-
InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
const EventEntry* entry) {
switch (entry->type) {
@@ -3154,9 +3284,6 @@ InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
switch (action) {
case AKEY_EVENT_ACTION_UP:
mKeyMementos.removeAt(i);
- if (isNeutral()) {
- mIsOutOfSync = false;
- }
return CONSISTENT;
case AKEY_EVENT_ACTION_DOWN:
@@ -3196,9 +3323,6 @@ InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotio
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_CANCEL:
mMotionMementos.removeAt(i);
- if (isNeutral()) {
- mIsOutOfSync = false;
- }
return CONSISTENT;
case AMOTION_EVENT_ACTION_DOWN:
@@ -3256,30 +3380,70 @@ void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry*
}
}
-void InputDispatcher::InputState::synthesizeCancelationEvents(
- Allocator* allocator, Vector<EventEntry*>& outEvents) const {
- for (size_t i = 0; i < mKeyMementos.size(); i++) {
+void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
+ Allocator* allocator, Vector<EventEntry*>& outEvents,
+ CancelationOptions options) {
+ for (size_t i = 0; i < mKeyMementos.size(); ) {
const KeyMemento& memento = mKeyMementos.itemAt(i);
- outEvents.push(allocator->obtainKeyEntry(now(),
- memento.deviceId, memento.source, 0,
- AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
- memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
+ if (shouldCancelEvent(memento.source, options)) {
+ outEvents.push(allocator->obtainKeyEntry(currentTime,
+ memento.deviceId, memento.source, 0,
+ AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
+ memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
+ mKeyMementos.removeAt(i);
+ } else {
+ i += 1;
+ }
}
for (size_t i = 0; i < mMotionMementos.size(); i++) {
const MotionMemento& memento = mMotionMementos.itemAt(i);
- outEvents.push(allocator->obtainMotionEntry(now(),
- memento.deviceId, memento.source, 0,
- AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
- memento.xPrecision, memento.yPrecision, memento.downTime,
- memento.pointerCount, memento.pointerIds, memento.pointerCoords));
+ if (shouldCancelEvent(memento.source, options)) {
+ outEvents.push(allocator->obtainMotionEntry(currentTime,
+ memento.deviceId, memento.source, 0,
+ AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
+ memento.xPrecision, memento.yPrecision, memento.downTime,
+ memento.pointerCount, memento.pointerIds, memento.pointerCoords));
+ mMotionMementos.removeAt(i);
+ } else {
+ i += 1;
+ }
}
}
void InputDispatcher::InputState::clear() {
mKeyMementos.clear();
mMotionMementos.clear();
- mIsOutOfSync = false;
+}
+
+void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
+ for (size_t i = 0; i < mMotionMementos.size(); i++) {
+ const MotionMemento& memento = mMotionMementos.itemAt(i);
+ if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
+ for (size_t j = 0; j < other.mMotionMementos.size(); ) {
+ const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
+ if (memento.deviceId == otherMemento.deviceId
+ && memento.source == otherMemento.source) {
+ other.mMotionMementos.removeAt(j);
+ } else {
+ j += 1;
+ }
+ }
+ other.mMotionMementos.push(memento);
+ }
+ }
+}
+
+bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
+ CancelationOptions options) {
+ switch (options) {
+ case CANCEL_POINTER_EVENTS:
+ return eventSource & AINPUT_SOURCE_CLASS_POINTER;
+ case CANCEL_NON_POINTER_EVENTS:
+ return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
+ default:
+ return true;
+ }
}
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 7adc764..0560bb8 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -796,10 +796,6 @@ int32_t InputMapper::getMetaState() {
return 0;
}
-bool InputMapper::applyStandardPolicyActions(nsecs_t when, int32_t policyActions) {
- return policyActions & InputReaderPolicyInterface::ACTION_DISPATCH;
-}
-
// --- SwitchInputMapper ---
@@ -823,11 +819,7 @@ void SwitchInputMapper::process(const RawEvent* rawEvent) {
}
void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
- uint32_t policyFlags = 0;
- int32_t policyActions = getPolicy()->interceptSwitch(
- when, switchCode, switchValue, policyFlags);
-
- applyStandardPolicyActions(when, policyActions);
+ getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
}
int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
@@ -983,29 +975,9 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
getContext()->updateGlobalMetaState();
}
- applyPolicyAndDispatch(when, policyFlags, down, keyCode, scanCode, newMetaState, downTime);
-}
-
-void KeyboardInputMapper::applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags, bool down,
- int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
- int32_t policyActions = getPolicy()->interceptKey(when,
- getDeviceId(), down, keyCode, scanCode, policyFlags);
-
- if (! applyStandardPolicyActions(when, policyActions)) {
- return; // event dropped
- }
-
- int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP;
- int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM;
- if (policyFlags & POLICY_FLAG_WOKE_HERE) {
- keyEventFlags |= AKEY_EVENT_FLAG_WOKE_HERE;
- }
- if (policyFlags & POLICY_FLAG_VIRTUAL) {
- keyEventFlags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- }
-
getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+ down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
+ AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
}
ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
@@ -1215,26 +1187,13 @@ void TrackballInputMapper::sync(nsecs_t when) {
}
} // release lock
- applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);
-
- mAccumulator.clear();
-}
-
-void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
- PointerCoords* pointerCoords, nsecs_t downTime) {
- uint32_t policyFlags = 0;
- int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
-
- if (! applyStandardPolicyActions(when, policyActions)) {
- return; // event dropped
- }
-
int32_t metaState = mContext->getGlobalMetaState();
int32_t pointerId = 0;
-
- getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags,
+ getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, 0,
motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime);
+ 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
+
+ mAccumulator.clear();
}
int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
@@ -2012,15 +1971,7 @@ void TouchInputMapper::reset() {
}
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
- // Apply generic policy actions.
-
uint32_t policyFlags = 0;
- int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
-
- if (! applyStandardPolicyActions(when, policyActions)) {
- mLastTouch.clear();
- return; // event dropped
- }
// Preprocess pointer data.
@@ -2160,24 +2111,11 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
} // release lock
// Dispatch virtual key.
- applyPolicyAndDispatchVirtualKey(when, policyFlags, keyEventAction, keyEventFlags,
- keyCode, scanCode, downTime);
- return touchResult;
-}
-
-void TouchInputMapper::applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
- int32_t keyEventAction, int32_t keyEventFlags,
- int32_t keyCode, int32_t scanCode, nsecs_t downTime) {
int32_t metaState = mContext->getGlobalMetaState();
-
policyFlags |= POLICY_FLAG_VIRTUAL;
- int32_t policyActions = getPolicy()->interceptKey(when, getDeviceId(),
- keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
-
- if (applyStandardPolicyActions(when, policyActions)) {
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
- }
+ getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+ keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+ return touchResult;
}
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 84a3e2c..f74f395 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -163,6 +163,7 @@ void MtpServer::run() {
mData.setOperationCode(operation);
mData.setTransactionID(transaction);
LOGV("sending data:");
+ mData.dump();
ret = mData.write(fd);
if (ret < 0) {
LOGE("request write returned %d, errno: %d", ret, errno);
@@ -177,6 +178,7 @@ void MtpServer::run() {
mResponse.setTransactionID(transaction);
LOGV("sending response %04X", mResponse.getResponseCode());
ret = mResponse.write(fd);
+ mResponse.dump();
if (ret < 0) {
LOGE("request write returned %d, errno: %d", ret, errno);
if (errno == ECANCELED) {
@@ -546,7 +548,7 @@ MtpResponseCode MtpServer::doGetObject() {
// send data header
mData.setOperationCode(mRequest.getOperationCode());
mData.setTransactionID(mRequest.getTransactionID());
- mData.writeDataHeader(mFD, fileLength);
+ mData.writeDataHeader(mFD, fileLength + MTP_CONTAINER_HEADER_SIZE);
// then transfer the file
int ret = ioctl(mFD, MTP_SEND_FILE, (unsigned long)&mfr);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 68e0e32..449bd4c 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1123,6 +1123,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
int keyCode, int metaState, int repeatCount, int policyFlags) {
+ if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
+ return false;
+ }
+
final boolean keyguardOn = keyguardOn();
final boolean down = (action == KeyEvent.ACTION_DOWN);
final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
@@ -1149,7 +1153,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (!down) {
mHomePressed = false;
- if (! canceled) {
+ if (!canceled) {
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallScreen at this point,
// and his ONLY options are to answer or reject the call.)
@@ -1831,7 +1835,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
int policyFlags, boolean isScreenOn) {
int result = ACTION_PASS_TO_USER;
-
+ if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
+ return result;
+ }
+
+ if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
+ }
+
final boolean isWakeKey = (policyFlags
& (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
diff --git a/preloaded-classes b/preloaded-classes
index 3317286..ee82a2c 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -626,7 +626,6 @@ com.android.internal.app.ChooserActivity
com.android.internal.app.ResolverActivity
com.android.internal.app.ResolverActivity$ResolveListAdapter
com.android.internal.appwidget.IAppWidgetService$Stub
-com.android.internal.content.SyncStateContentProviderHelper
com.android.internal.graphics.NativeUtils
com.android.internal.location.DummyLocationProvider
com.android.internal.logging.AndroidHandler
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 808c679..d09dfff 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -320,6 +320,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
// Callback is disabled by default
mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
mOrientation = 0;
+ mPreviewWindowFlag = 0;
mOrientationChanged = false;
mPlayShutterSound = true;
cameraService->setCameraBusy(cameraId);
@@ -508,6 +509,8 @@ status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
if (mUseOverlay) {
result = setOverlay();
} else if (mPreviewWindow != 0) {
+ native_window_set_buffers_transform(mPreviewWindow.get(),
+ mPreviewWindowFlag);
result = mHardware->setPreviewWindow(mPreviewWindow);
}
}
@@ -633,7 +636,10 @@ status_t CameraService::Client::startPreviewMode() {
if (result != NO_ERROR) return result;
result = mHardware->startPreview();
} else {
- // XXX: Set the orientation of the ANativeWindow.
+ if (mPreviewWindow != 0) {
+ native_window_set_buffers_transform(mPreviewWindow.get(),
+ mPreviewWindowFlag);
+ }
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
}
@@ -818,15 +824,19 @@ status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t a
switch (arg1) {
case 0:
orientation = ISurface::BufferHeap::ROT_0;
+ mPreviewWindowFlag = 0;
break;
case 90:
orientation = ISurface::BufferHeap::ROT_90;
+ mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_90;
break;
case 180:
orientation = ISurface::BufferHeap::ROT_180;
+ mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_180;
break;
case 270:
orientation = ISurface::BufferHeap::ROT_270;
+ mPreviewWindowFlag = NATIVE_WINDOW_TRANSFORM_ROT_270;
break;
default:
return BAD_VALUE;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index d57364a..c8e0c88 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -166,6 +166,7 @@ private:
sp<CameraService> mCameraService; // immutable after constructor
sp<ICameraClient> mCameraClient;
int mCameraId; // immutable after constructor
+ int mCameraFacing; // immutable after constructor
pid_t mClientPid;
sp<CameraHardwareInterface> mHardware; // cleared after disconnect()
bool mUseOverlay; // immutable after constructor
@@ -176,6 +177,7 @@ private:
int mOrientation; // Current display orientation
// True if display orientation has been changed. This is only used in overlay.
int mOrientationChanged;
+ int mPreviewWindowFlag;
bool mPlayShutterSound;
// Ensures atomicity among the public methods
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 4e2f1e3..4931cc7 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -124,6 +124,14 @@ class AlarmManagerService extends IAlarmManager.Stub {
public AlarmManagerService(Context context) {
mContext = context;
mDescriptor = init();
+
+ // We have to set current TimeZone info to kernel
+ // because kernel doesn't keep this after reboot
+ String tz = SystemProperties.get(TIMEZONE_PROPERTY);
+ if (tz != null) {
+ setTimeZone(tz);
+ }
+
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index fe306b3..cb4071a 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -49,6 +49,8 @@ import java.util.Properties;
public class InputManager {
static final String TAG = "InputManager";
+ private static final boolean DEBUG = false;
+
private final Callbacks mCallbacks;
private final Context mContext;
private final WindowManagerService mWindowManagerService;
@@ -131,7 +133,9 @@ public class InputManager {
throw new IllegalArgumentException("Invalid display id or dimensions.");
}
- Slog.i(TAG, "Setting display #" + displayId + " size to " + width + "x" + height);
+ if (DEBUG) {
+ Slog.d(TAG, "Setting display #" + displayId + " size to " + width + "x" + height);
+ }
nativeSetDisplaySize(displayId, width, height);
}
@@ -140,7 +144,9 @@ public class InputManager {
throw new IllegalArgumentException("Invalid rotation.");
}
- Slog.i(TAG, "Setting display #" + displayId + " orientation to " + rotation);
+ if (DEBUG) {
+ Slog.d(TAG, "Setting display #" + displayId + " orientation to " + rotation);
+ }
nativeSetDisplayOrientation(displayId, rotation);
}
@@ -378,11 +384,6 @@ public class InputManager {
private static final String CALIBRATION_DIR_PATH = "usr/idc/";
@SuppressWarnings("unused")
- public void virtualKeyDownFeedback() {
- mWindowManagerService.mInputMonitor.virtualKeyDownFeedback();
- }
-
- @SuppressWarnings("unused")
public void notifyConfigurationChanged(long whenNanos) {
mWindowManagerService.sendNewConfiguration();
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 59f7434..8be980f 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -804,7 +804,9 @@ public class WindowManagerService extends IWindowManager.Stub
// stop intercepting input
mDragState.unregister();
- mInputMonitor.updateInputWindowsLw();
+ synchronized (mWindowMap) {
+ mInputMonitor.updateInputWindowsLw();
+ }
// free our resources and drop all the object references
mDragState.reset();
@@ -5670,13 +5672,6 @@ public class WindowManagerService extends IWindowManager.Stub
mTempInputWindows.clear();
}
- /* Provides feedback for a virtual key down. */
- public void virtualKeyDownFeedback() {
- synchronized (mWindowMap) {
- mPolicy.performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
- }
- }
-
/* Notifies that the lid switch changed state. */
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
@@ -8128,7 +8123,8 @@ public class WindowManagerService extends IWindowManager.Stub
WindowState win = allAppWindows.get(i);
if (win == startingWindow || win.mAppFreezing
|| win.mViewVisibility != View.VISIBLE
- || win.mAttrs.type == TYPE_APPLICATION_STARTING) {
+ || win.mAttrs.type == TYPE_APPLICATION_STARTING
+ || win.mDestroying) {
continue;
}
if (DEBUG_VISIBILITY) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3084c16..83351bc 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6886,6 +6886,9 @@ public final class ActivityManagerService extends ActivityManagerNative
sb.append("Subject: ").append(subject).append("\n");
}
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
+ if (Debug.isDebuggerConnected()) {
+ sb.append("Debugger: Connected\n");
+ }
sb.append("\n");
// Do the rest in a worker thread to avoid blocking the caller on I/O
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index 8e7cadc..397a84a 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -67,6 +67,7 @@ struct BatteryManagerConstants {
jint healthDead;
jint healthOverVoltage;
jint healthUnspecifiedFailure;
+ jint healthCold;
};
static BatteryManagerConstants gConstants;
@@ -104,6 +105,7 @@ static jint getBatteryStatus(const char* status)
static jint getBatteryHealth(const char* status)
{
switch (status[0]) {
+ case 'C': return gConstants.healthCold; // Cold
case 'D': return gConstants.healthDead; // Dead
case 'G': return gConstants.healthGood; // Good
case 'O': {
@@ -390,6 +392,9 @@ int register_android_server_BatteryService(JNIEnv* env)
gConstants.healthUnspecifiedFailure = env->GetStaticIntField(clazz,
env->GetStaticFieldID(clazz, "BATTERY_HEALTH_UNSPECIFIED_FAILURE", "I"));
+ gConstants.healthCold = env->GetStaticIntField(clazz,
+ env->GetStaticFieldID(clazz, "BATTERY_HEALTH_COLD", "I"));
+
return jniRegisterNativeMethods(env, "com/android/server/BatteryService", sMethods, NELEM(sMethods));
}
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 4f1fab7..e15e8d8 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -50,7 +50,6 @@ static struct {
jmethodID notifyLidSwitchChanged;
jmethodID notifyInputChannelBroken;
jmethodID notifyANR;
- jmethodID virtualKeyDownFeedback;
jmethodID interceptKeyBeforeQueueing;
jmethodID interceptKeyBeforeDispatching;
jmethodID checkInjectEventsPermission;
@@ -182,11 +181,6 @@ public:
virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation);
- virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
- bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags);
- virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
- uint32_t& policyFlags);
- virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags);
virtual bool filterTouchEvents();
virtual bool filterJumpyTouchEvents();
virtual void getVirtualKeyDefinitions(const String8& deviceName,
@@ -197,6 +191,8 @@ public:
/* --- InputDispatcherPolicyInterface implementation --- */
+ virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+ uint32_t policyFlags);
virtual void notifyConfigurationChanged(nsecs_t when);
virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
const sp<InputChannel>& inputChannel);
@@ -204,6 +200,10 @@ public:
virtual nsecs_t getKeyRepeatTimeout();
virtual nsecs_t getKeyRepeatDelay();
virtual int32_t getMaxEventsPerSecond();
+ virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
+ int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
+ uint32_t& policyFlags);
+ virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags);
virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
@@ -254,7 +254,6 @@ private:
static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
- static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
static inline JNIEnv* jniEnv() {
@@ -290,37 +289,6 @@ void NativeInputManager::dump(String8& dump) {
dump.append("\n");
}
-bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
- // Special keys that the WindowManagerPolicy might care about.
- switch (keyCode) {
- case AKEYCODE_VOLUME_UP:
- case AKEYCODE_VOLUME_DOWN:
- case AKEYCODE_ENDCALL:
- case AKEYCODE_POWER:
- case AKEYCODE_CALL:
- case AKEYCODE_HOME:
- case AKEYCODE_MENU:
- case AKEYCODE_SEARCH:
- // media keys
- case AKEYCODE_HEADSETHOOK:
- case AKEYCODE_MEDIA_PLAY_PAUSE:
- case AKEYCODE_MEDIA_STOP:
- case AKEYCODE_MEDIA_NEXT:
- case AKEYCODE_MEDIA_PREVIOUS:
- case AKEYCODE_MEDIA_REWIND:
- case AKEYCODE_MEDIA_FAST_FORWARD:
- // The policy always cares about these keys.
- return true;
- default:
- // We need to pass all keys to the policy in the following cases:
- // - screen is off
- // - keyguard is visible
- // - policy is performing key chording
- //return ! isScreenOn || keyguardVisible || chording;
- return true; // XXX stubbed out for now
- }
-}
-
bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
if (env->ExceptionCheck()) {
LOGE("An exception was thrown by callback '%s'.", methodName);
@@ -453,115 +421,6 @@ bool NativeInputManager::getDisplayInfo(int32_t displayId,
return result;
}
-bool NativeInputManager::isScreenOn() {
- return android_server_PowerManagerService_isScreenOn();
-}
-
-bool NativeInputManager::isScreenBright() {
- return android_server_PowerManagerService_isScreenBright();
-}
-
-int32_t NativeInputManager::interceptKey(nsecs_t when,
- int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
-#if DEBUG_INPUT_READER_POLICY
- LOGD("interceptKey - when=%lld, deviceId=%d, down=%d, keyCode=%d, scanCode=%d, "
- "policyFlags=0x%x",
- when, deviceId, down, keyCode, scanCode, policyFlags);
-#endif
-
- if (down && (policyFlags & POLICY_FLAG_VIRTUAL)) {
- JNIEnv* env = jniEnv();
- env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
- checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
- }
-
- const int32_t WM_ACTION_PASS_TO_USER = 1;
- const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
- const int32_t WM_ACTION_GO_TO_SLEEP = 4;
-
- bool isScreenOn = this->isScreenOn();
- bool isScreenBright = this->isScreenBright();
-
- jint wmActions = 0;
- if (isPolicyKey(keyCode, isScreenOn)) {
- JNIEnv* env = jniEnv();
-
- wmActions = env->CallIntMethod(mCallbacksObj,
- gCallbacksClassInfo.interceptKeyBeforeQueueing,
- when, keyCode, down, policyFlags, isScreenOn);
- if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
- wmActions = 0;
- }
- } else {
- wmActions = WM_ACTION_PASS_TO_USER;
- }
-
- int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
- if (! isScreenOn) {
- // Key presses and releases wake the device.
- policyFlags |= POLICY_FLAG_WOKE_HERE;
- }
-
- if (! isScreenBright) {
- // Key presses and releases brighten the screen if dimmed.
- policyFlags |= POLICY_FLAG_BRIGHT_HERE;
- }
-
- if (wmActions & WM_ACTION_GO_TO_SLEEP) {
- android_server_PowerManagerService_goToSleep(when);
- }
-
- if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
- android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
- }
-
- if (wmActions & WM_ACTION_PASS_TO_USER) {
- actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
- }
-
- return actions;
-}
-
-int32_t NativeInputManager::interceptGeneric(nsecs_t when, uint32_t& policyFlags) {
-#if DEBUG_INPUT_READER_POLICY
- LOGD("interceptGeneric - when=%lld, policyFlags=0x%x", when, policyFlags);
-#endif
-
- int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
- if (isScreenOn()) {
- // Only dispatch events when the device is awake.
- // Do not wake the device.
- actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
-
- if (! isScreenBright()) {
- // Brighten the screen if dimmed.
- policyFlags |= POLICY_FLAG_BRIGHT_HERE;
- }
- }
-
- return actions;
-}
-
-int32_t NativeInputManager::interceptSwitch(nsecs_t when, int32_t switchCode,
- int32_t switchValue, uint32_t& policyFlags) {
-#if DEBUG_INPUT_READER_POLICY
- LOGD("interceptSwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
- when, switchCode, switchValue, policyFlags);
-#endif
-
- JNIEnv* env = jniEnv();
-
- switch (switchCode) {
- case SW_LID:
- env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
- when, switchValue == 0);
- checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
- break;
- }
-
- return InputReaderPolicyInterface::ACTION_NONE;
-}
-
bool NativeInputManager::filterTouchEvents() {
if (mFilterTouchEvents < 0) {
JNIEnv* env = jniEnv();
@@ -691,6 +550,24 @@ void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDevi
}
}
+void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
+ int32_t switchValue, uint32_t policyFlags) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+ LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
+ when, switchCode, switchValue, policyFlags);
+#endif
+
+ JNIEnv* env = jniEnv();
+
+ switch (switchCode) {
+ case SW_LID:
+ env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
+ when, switchValue == 0);
+ checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
+ break;
+ }
+}
+
void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("notifyConfigurationChanged - when=%lld", when);
@@ -943,13 +820,88 @@ void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
}
-bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
- const KeyEvent* keyEvent, uint32_t policyFlags) {
+bool NativeInputManager::isScreenOn() {
+ return android_server_PowerManagerService_isScreenOn();
+}
+
+bool NativeInputManager::isScreenBright() {
+ return android_server_PowerManagerService_isScreenBright();
+}
+
+void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
+ int32_t deviceId, int32_t action, int32_t &flags,
+ int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+ LOGD("interceptKeyBeforeQueueing - when=%lld, deviceId=%d, action=%d, flags=%d, "
+ "keyCode=%d, scanCode=%d, policyFlags=0x%x",
+ when, deviceId, action, flags, keyCode, scanCode, policyFlags);
+#endif
+
+ if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
+ policyFlags |= POLICY_FLAG_VIRTUAL;
+ flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
+ }
+
+ const int32_t WM_ACTION_PASS_TO_USER = 1;
+ const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
+ const int32_t WM_ACTION_GO_TO_SLEEP = 4;
+
bool isScreenOn = this->isScreenOn();
- if (! isPolicyKey(keyEvent->getKeyCode(), isScreenOn)) {
- return false;
+ bool isScreenBright = this->isScreenBright();
+
+ JNIEnv* env = jniEnv();
+ jint wmActions = env->CallIntMethod(mCallbacksObj,
+ gCallbacksClassInfo.interceptKeyBeforeQueueing,
+ when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
+ if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
+ wmActions = 0;
+ }
+
+ if (policyFlags & POLICY_FLAG_TRUSTED) {
+ if (! isScreenOn) {
+ // Key presses and releases wake the device.
+ policyFlags |= POLICY_FLAG_WOKE_HERE;
+ flags |= AKEY_EVENT_FLAG_WOKE_HERE;
+ }
+
+ if (! isScreenBright) {
+ // Key presses and releases brighten the screen if dimmed.
+ policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+ }
+
+ if (wmActions & WM_ACTION_GO_TO_SLEEP) {
+ android_server_PowerManagerService_goToSleep(when);
+ }
+
+ if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
+ android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
+ }
+ }
+
+ if (wmActions & WM_ACTION_PASS_TO_USER) {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
+}
+void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+ LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
+#endif
+
+ if (isScreenOn()) {
+ // Only dispatch events when the device is awake.
+ // Do not wake the device.
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
+
+ if ((policyFlags & POLICY_FLAG_TRUSTED) && !isScreenBright()) {
+ // Brighten the screen if dimmed.
+ policyFlags |= POLICY_FLAG_BRIGHT_HERE;
+ }
+ }
+}
+
+bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
+ const KeyEvent* keyEvent, uint32_t policyFlags) {
JNIEnv* env = jniEnv();
// Note: inputChannel may be null.
@@ -1281,7 +1233,6 @@ static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
if (checkInputManagerUnitialized(env)) {
- LOGD("input manager uninitialized; bailing");
return false;
}
@@ -1291,7 +1242,6 @@ static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env
android_view_InputChannel_getInputChannel(env, toChannelObj);
if (fromChannel == NULL || toChannel == NULL) {
- LOGD("bailing because from=%p to=%p", fromChannel, toChannel);
return false;
}
@@ -1387,9 +1337,6 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
"notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
- GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
- "virtualKeyDownFeedback", "()V");
-
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
"interceptKeyBeforeQueueing", "(JIZIZ)I");
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index b312fb1..bd722d7 100755
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -238,7 +238,11 @@ static const GpsInterface* get_gps_interface() {
return interface;
}
-static const GpsInterface* GetGpsInterface() {
+static const GpsInterface* GetGpsInterface(JNIEnv* env, jobject obj) {
+ // this must be set before calling into the HAL library
+ if (!mCallbacksObj)
+ mCallbacksObj = env->NewGlobalRef(obj);
+
if (!sGpsInterface) {
sGpsInterface = get_gps_interface();
if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) {
@@ -249,9 +253,9 @@ static const GpsInterface* GetGpsInterface() {
return sGpsInterface;
}
-static const AGpsInterface* GetAGpsInterface()
+static const AGpsInterface* GetAGpsInterface(JNIEnv* env, jobject obj)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (!interface)
return NULL;
@@ -263,9 +267,9 @@ static const AGpsInterface* GetAGpsInterface()
return sAGpsInterface;
}
-static const GpsNiInterface* GetNiInterface()
+static const GpsNiInterface* GetNiInterface(JNIEnv* env, jobject obj)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (!interface)
return NULL;
@@ -277,9 +281,9 @@ static const GpsNiInterface* GetNiInterface()
return sGpsNiInterface;
}
-static const AGpsRilInterface* GetAGpsRilInterface()
+static const AGpsRilInterface* GetAGpsRilInterface(JNIEnv* env, jobject obj)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (!interface)
return NULL;
@@ -310,11 +314,7 @@ static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, j
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
{
- // this must be set before calling into the HAL library
- if (!mCallbacksObj)
- mCallbacksObj = env->NewGlobalRef(obj);
-
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (!interface)
return false;
@@ -326,7 +326,7 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o
static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
interface->cleanup();
}
@@ -334,7 +334,7 @@ static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject ob
static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* env, jobject obj,
jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
return (interface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy,
preferred_time) == 0);
@@ -344,7 +344,7 @@ static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* e
static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
return (interface->start() == 0);
else
@@ -353,7 +353,7 @@ static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject
static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
return (interface->stop() == 0);
else
@@ -362,7 +362,7 @@ static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject o
static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
interface->delete_aiding_data(flags);
}
@@ -402,7 +402,7 @@ static void android_location_GpsLocationProvider_agps_set_reference_location_cel
jobject obj, jint type, jint mcc, jint mnc, jint lac, jint cid)
{
AGpsRefLocation location;
- const AGpsRilInterface* interface = GetAGpsRilInterface();
+ const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
if (!interface) {
LOGE("no AGPS RIL interface in agps_set_reference_location_cellid");
return;
@@ -429,7 +429,7 @@ static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* en
jobject obj, jbyteArray ni_msg, jint size)
{
size_t sz;
- const AGpsRilInterface* interface = GetAGpsRilInterface();
+ const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
if (!interface) {
LOGE("no AGPS RIL interface in send_ni_message");
return;
@@ -445,7 +445,7 @@ static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* en
static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env,
jobject obj, jint type, jstring setid_string)
{
- const AGpsRilInterface* interface = GetAGpsRilInterface();
+ const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
if (!interface) {
LOGE("no AGPS RIL interface in agps_set_id");
return;
@@ -472,7 +472,7 @@ static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject
static void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj,
jlong time, jlong timeReference, jint uncertainty)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
interface->inject_time(time, timeReference, uncertainty);
}
@@ -480,7 +480,7 @@ static void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobjec
static void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj,
jdouble latitude, jdouble longitude, jfloat accuracy)
{
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (interface)
interface->inject_location(latitude, longitude, accuracy);
}
@@ -488,7 +488,7 @@ static void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jo
static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj)
{
if (!sGpsXtraInterface) {
- const GpsInterface* interface = GetGpsInterface();
+ const GpsInterface* interface = GetGpsInterface(env, obj);
if (!interface)
return false;
sGpsXtraInterface = (const GpsXtraInterface*)interface->get_extension(GPS_XTRA_INTERFACE);
@@ -513,7 +513,7 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j
static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
{
- const AGpsInterface* interface = GetAGpsInterface();
+ const AGpsInterface* interface = GetAGpsInterface(env, obj);
if (!interface) {
LOGE("no AGPS interface in agps_data_conn_open");
return;
@@ -529,7 +529,7 @@ static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env
static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj)
{
- const AGpsInterface* interface = GetAGpsInterface();
+ const AGpsInterface* interface = GetAGpsInterface(env, obj);
if (!interface) {
LOGE("no AGPS interface in agps_data_conn_open");
return;
@@ -539,7 +539,7 @@ static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* e
static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
{
- const AGpsInterface* interface = GetAGpsInterface();
+ const AGpsInterface* interface = GetAGpsInterface(env, obj);
if (!interface) {
LOGE("no AGPS interface in agps_data_conn_open");
return;
@@ -550,7 +550,7 @@ static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* e
static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
jint type, jstring hostname, jint port)
{
- const AGpsInterface* interface = GetAGpsInterface();
+ const AGpsInterface* interface = GetAGpsInterface(env, obj);
if (!interface) {
LOGE("no AGPS interface in agps_data_conn_open");
return;
@@ -563,7 +563,7 @@ static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jo
static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj,
jint notifId, jint response)
{
- const GpsNiInterface* interface = GetNiInterface();
+ const GpsNiInterface* interface = GetNiInterface(env, obj);
if (!interface) {
LOGE("no NI interface in send_ni_response");
return;
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index e37733c..893ae88 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1823,12 +1823,19 @@ public class PhoneNumberUtils
}
/**
+ * Determines if the specified number is actually a URI
+ * (i.e. a SIP address) rather than a regular PSTN phone number,
+ * based on whether or not the number contains an "@" character.
+ *
* @hide
* @param number
* @return true if number contains @
*/
public static boolean isUriNumber(String number) {
- return number != null && number.contains("@");
+ // Note we allow either "@" or "%40" to indicate a URI, in case
+ // the passed-in string is URI-escaped. (Neither "@" nor "%40"
+ // will ever be found in a legal PSTN number.)
+ return number != null && (number.contains("@") || number.contains("%40"));
}
/**
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 8c2280b..35d5564 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1969,26 +1969,30 @@ public final class RIL extends BaseCommands implements CommandsInterface {
sendScreenState(true);
}
- private void setRadioStateFromRILInt(int state) {
- RadioState newState;
+ private RadioState getRadioStateFromInt(int stateInt) {
+ RadioState state;
/* RIL_RadioState ril.h */
- switch(state) {
- case 0: newState = RadioState.RADIO_OFF; break;
- case 1: newState = RadioState.RADIO_UNAVAILABLE; break;
- case 2: newState = RadioState.SIM_NOT_READY; break;
- case 3: newState = RadioState.SIM_LOCKED_OR_ABSENT; break;
- case 4: newState = RadioState.SIM_READY; break;
- case 5: newState = RadioState.RUIM_NOT_READY; break;
- case 6: newState = RadioState.RUIM_READY; break;
- case 7: newState = RadioState.RUIM_LOCKED_OR_ABSENT; break;
- case 8: newState = RadioState.NV_NOT_READY; break;
- case 9: newState = RadioState.NV_READY; break;
+ switch(stateInt) {
+ case 0: state = RadioState.RADIO_OFF; break;
+ case 1: state = RadioState.RADIO_UNAVAILABLE; break;
+ case 2: state = RadioState.SIM_NOT_READY; break;
+ case 3: state = RadioState.SIM_LOCKED_OR_ABSENT; break;
+ case 4: state = RadioState.SIM_READY; break;
+ case 5: state = RadioState.RUIM_NOT_READY; break;
+ case 6: state = RadioState.RUIM_READY; break;
+ case 7: state = RadioState.RUIM_LOCKED_OR_ABSENT; break;
+ case 8: state = RadioState.NV_NOT_READY; break;
+ case 9: state = RadioState.NV_READY; break;
default:
throw new RuntimeException(
- "Unrecognized RIL_RadioState: " +state);
+ "Unrecognized RIL_RadioState: " + stateInt);
}
+ return state;
+ }
+
+ private void switchToRadioState(RadioState newState) {
if (mInitialRadioStateChange) {
if (newState.isOn()) {
@@ -2369,9 +2373,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
switch(response) {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
/* has bonus radio state int */
- setRadioStateFromRILInt(p.readInt());
+ RadioState newState = getRadioStateFromInt(p.readInt());
+ if (RILJ_LOGD) unsljLogMore(response, newState.toString());
- if (RILJ_LOGD) unsljLogMore(response, mState.toString());
+ switchToRadioState(newState);
break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 878d30c..a951040 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -18,7 +18,6 @@ package com.android.internal.telephony.sip;
import android.content.Context;
import android.net.rtp.AudioGroup;
-import android.net.rtp.AudioStream;
import android.net.sip.SipAudioCall;
import android.net.sip.SipErrorCode;
import android.net.sip.SipException;
@@ -29,11 +28,9 @@ import android.os.AsyncResult;
import android.os.Message;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
-import android.text.TextUtils;
import android.util.Log;
import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallerInfo;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.Phone;
@@ -385,40 +382,6 @@ public class SipPhone extends SipPhoneBase {
}
}
- private CallerInfo createCallerInfo(String number, SipProfile callee) {
- SipProfile p = callee;
- String name = p.getDisplayName();
- if (TextUtils.isEmpty(name)) name = p.getUserName();
- CallerInfo info = new CallerInfo();
- info.name = name;
- info.phoneNumber = number;
- if (DEBUG) {
- Log.d(LOG_TAG, "create caller info from scratch:");
- Log.d(LOG_TAG, " name: " + info.name);
- Log.d(LOG_TAG, " numb: " + info.phoneNumber);
- }
- return info;
- }
-
- // from contacts
- private CallerInfo findCallerInfo(String number) {
- CallerInfo info = CallerInfo.getCallerInfo(mContext, number);
- if ((info == null) || (info.name == null)) return null;
- if (DEBUG) {
- Log.d(LOG_TAG, "got caller info from contact:");
- Log.d(LOG_TAG, " name: " + info.name);
- Log.d(LOG_TAG, " numb: " + info.phoneNumber);
- Log.d(LOG_TAG, " pres: " + info.numberPresentation);
- }
- return info;
- }
-
- private CallerInfo getCallerInfo(String number, SipProfile callee) {
- CallerInfo info = findCallerInfo(number);
- if (info == null) info = createCallerInfo(number, callee);
- return info;
- }
-
Connection dial(String originalNumber) throws SipException {
String calleeSipUri = originalNumber;
if (!calleeSipUri.contains("@")) {
@@ -427,8 +390,7 @@ public class SipPhone extends SipPhoneBase {
try {
SipProfile callee =
new SipProfile.Builder(calleeSipUri).build();
- CallerInfo info = getCallerInfo(originalNumber, callee);
- SipConnection c = new SipConnection(this, callee, info);
+ SipConnection c = new SipConnection(this, callee);
connections.add(c);
c.dial();
setState(Call.State.DIALING);
@@ -464,10 +426,7 @@ public class SipPhone extends SipPhoneBase {
void initIncomingCall(SipAudioCall sipAudioCall, boolean makeCallWait) {
SipProfile callee = sipAudioCall.getPeerProfile();
- CallerInfo info = findCallerInfo(getUriString(callee));
- if (info == null) info = findCallerInfo(callee.getUserName());
- if (info == null) info = findCallerInfo(callee.getDisplayName());
- SipConnection c = new SipConnection(this, callee, info);
+ SipConnection c = new SipConnection(this, callee);
connections.add(c);
Call.State newState = makeCallWait ? State.WAITING : State.INCOMING;
@@ -703,12 +662,10 @@ public class SipPhone extends SipPhoneBase {
}
};
- public SipConnection(SipCall owner, SipProfile callee,
- CallerInfo info) {
+ public SipConnection(SipCall owner, SipProfile callee) {
super(getUriString(callee));
mOwner = owner;
mPeer = callee;
- setUserData(info);
}
void initIncomingCall(SipAudioCall sipAudioCall, Call.State newState) {
diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java
index 050eddc..2514262 100644
--- a/voip/java/com/android/server/sip/SipHelper.java
+++ b/voip/java/com/android/server/sip/SipHelper.java
@@ -238,6 +238,8 @@ class SipHelper {
ClientTransaction tid = responseEvent.getClientTransaction();
ClientTransaction ct = authenticationHelper.handleChallenge(
responseEvent.getResponse(), tid, mSipProvider, 5);
+ if (DEBUG) Log.d(TAG, "send request with challenge response: "
+ + ct.getRequest());
ct.sendRequest();
return ct;
}