Merge "Only install after MCS success" into gingerbread
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 1fe85e6..9a55a6f 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -37,6 +37,7 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.ServiceManager;
+import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
@@ -1056,8 +1057,8 @@
data.enforceInterface(IActivityManager.descriptor);
IBinder app = data.readStrongBinder();
int violationMask = data.readInt();
- ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
- handleApplicationStrictModeViolation(app, violationMask, ci);
+ StrictMode.ViolationInfo info = new StrictMode.ViolationInfo(data);
+ handleApplicationStrictModeViolation(app, violationMask, info);
reply.writeNoException();
return true;
}
@@ -2571,14 +2572,14 @@
public void handleApplicationStrictModeViolation(IBinder app,
int violationMask,
- ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
+ StrictMode.ViolationInfo info) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app);
data.writeInt(violationMask);
- crashInfo.writeToParcel(data, 0);
+ info.writeToParcel(data, 0);
mRemote.transact(HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION, data, reply, 0);
reply.readException();
reply.recycle();
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 30815c3..8f940d5 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -24,6 +24,7 @@
import android.content.pm.ResolveInfo;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Printer;
@@ -74,18 +75,15 @@
public static final int TYPE_BATTERY = 3;
/**
- * An error report about a StrictMode violation.
- */
- public static final int TYPE_STRICT_MODE_VIOLATION = 4;
-
- /**
- * An error report about a StrictMode violation.
+ * A report from a user to a developer about a running service that the
+ * user doesn't think should be running.
*/
public static final int TYPE_RUNNING_SERVICE = 5;
/**
* Type of this report. Can be one of {@link #TYPE_NONE},
- * {@link #TYPE_CRASH}, {@link #TYPE_ANR}, or {@link #TYPE_BATTERY}.
+ * {@link #TYPE_CRASH}, {@link #TYPE_ANR}, {@link #TYPE_BATTERY},
+ * or {@link #TYPE_RUNNING_SERVICE}.
*/
public int type;
@@ -133,7 +131,7 @@
* of BatteryInfo; otherwise null.
*/
public BatteryInfo batteryInfo;
-
+
/**
* If this report is of type {@link #TYPE_RUNNING_SERVICE}, contains an instance
* of RunningServiceInfo; otherwise null.
@@ -278,10 +276,6 @@
/**
* Describes an application crash.
- *
- * <p>This is also used to marshal around stack traces of ANRs and
- * StrictMode violations which aren't necessarily crashes, but have
- * a lot in common.
*/
public static class CrashInfo {
/**
@@ -320,12 +314,6 @@
public String stackTrace;
/**
- * For StrictMode violations, the wall time duration of the
- * violation, when known.
- */
- public long durationMillis = -1;
-
- /**
* Create an uninitialized instance of CrashInfo.
*/
public CrashInfo() {
@@ -368,7 +356,6 @@
throwMethodName = in.readString();
throwLineNumber = in.readInt();
stackTrace = in.readString();
- durationMillis = in.readLong();
}
/**
@@ -382,7 +369,6 @@
dest.writeString(throwMethodName);
dest.writeInt(throwLineNumber);
dest.writeString(stackTrace);
- dest.writeLong(durationMillis);
}
/**
@@ -396,9 +382,6 @@
pw.println(prefix + "throwMethodName: " + throwMethodName);
pw.println(prefix + "throwLineNumber: " + throwLineNumber);
pw.println(prefix + "stackTrace: " + stackTrace);
- if (durationMillis != -1) {
- pw.println(prefix + "durationMillis: " + durationMillis);
- }
}
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 20c9a80..81b28b9 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -19,10 +19,10 @@
import android.content.ComponentName;
import android.content.ContentProviderNative;
import android.content.IContentProvider;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.IIntentSender;
-import android.content.IIntentReceiver;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
@@ -31,14 +31,15 @@
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Debug;
-import android.os.RemoteException;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
-import android.os.Parcelable;
import android.os.ParcelFileDescriptor;
-import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.StrictMode;
import java.util.List;
@@ -260,7 +261,7 @@
// bit violated and penalty bits to be executed by the
// ActivityManagerService remaining set.
public void handleApplicationStrictModeViolation(IBinder app, int violationMask,
- ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
+ StrictMode.ViolationInfo crashInfo) throws RemoteException;
/*
* This will deliver the specified signal to all the persistent processes. Currently only
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index d4b0500..ac12e10 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -18,6 +18,7 @@
import android.app.ActivityManagerNative;
import android.app.ApplicationErrorReport;
import android.util.Log;
+import android.util.Printer;
import com.android.internal.os.RuntimeInit;
@@ -97,9 +98,9 @@
* via Parcel.writeNoException() (amusingly) where the caller can
* choose how to react.
*/
- private static final ThreadLocal<ArrayList<ApplicationErrorReport.CrashInfo>> gatheredViolations =
- new ThreadLocal<ArrayList<ApplicationErrorReport.CrashInfo>>() {
- @Override protected ArrayList<ApplicationErrorReport.CrashInfo> initialValue() {
+ private static final ThreadLocal<ArrayList<ViolationInfo>> gatheredViolations =
+ new ThreadLocal<ArrayList<ViolationInfo>>() {
+ @Override protected ArrayList<ViolationInfo> initialValue() {
// Starts null to avoid unnecessary allocations when
// checking whether there are any violations or not in
// hasGatheredViolations() below.
@@ -240,7 +241,9 @@
if ((mPolicyMask & DISALLOW_DISK_WRITE) == 0) {
return;
}
- startHandlingViolationException(new StrictModeDiskWriteViolation(mPolicyMask));
+ BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask);
+ e.fillInStackTrace();
+ startHandlingViolationException(e);
}
// Part of BlockGuard.Policy interface:
@@ -248,7 +251,9 @@
if ((mPolicyMask & DISALLOW_DISK_READ) == 0) {
return;
}
- startHandlingViolationException(new StrictModeDiskReadViolation(mPolicyMask));
+ BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask);
+ e.fillInStackTrace();
+ startHandlingViolationException(e);
}
// Part of BlockGuard.Policy interface:
@@ -256,7 +261,9 @@
if ((mPolicyMask & DISALLOW_NETWORK) == 0) {
return;
}
- startHandlingViolationException(new StrictModeNetworkViolation(mPolicyMask));
+ BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask);
+ e.fillInStackTrace();
+ startHandlingViolationException(e);
}
public void setPolicyMask(int policyMask) {
@@ -269,31 +276,70 @@
// thread and, if so, uses it to roughly measure how long the
// violation took.
void startHandlingViolationException(BlockGuard.BlockGuardPolicyException e) {
- e.fillInStackTrace();
- final ApplicationErrorReport.CrashInfo crashInfo = new ApplicationErrorReport.CrashInfo(e);
- crashInfo.durationMillis = -1; // unknown
- final int savedPolicy = mPolicyMask;
+ final ViolationInfo info = new ViolationInfo(e, e.getPolicy());
+ info.violationUptimeMillis = SystemClock.uptimeMillis();
+ handleViolationWithTimingAttempt(info);
+ }
+ private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed =
+ new ThreadLocal<ArrayList<ViolationInfo>>() {
+ @Override protected ArrayList<ViolationInfo> initialValue() {
+ return new ArrayList<ViolationInfo>();
+ }
+ };
+
+ // Attempts to fill in the provided ViolationInfo's
+ // durationMillis field if this thread has a Looper we can use
+ // to measure with. We measure from the time of violation
+ // until the time the looper is idle again (right before
+ // the next epoll_wait)
+ void handleViolationWithTimingAttempt(final ViolationInfo info) {
Looper looper = Looper.myLooper();
+
+ // Without a Looper, we're unable to time how long the
+ // violation takes place. This case should be rare, as
+ // most users will care about timing violations that
+ // happen on their main UI thread. Note that this case is
+ // also hit when a violation takes place in a Binder
+ // thread, in "gather" mode. In this case, the duration
+ // of the violation is computed by the ultimate caller and
+ // its Looper, if any.
+ // TODO: if in gather mode, ignore Looper.myLooper() and always
+ // go into this immediate mode?
if (looper == null) {
- // Without a Looper, we're unable to time how long the
- // violation takes place. This case should be rare,
- // as most users will care about timing violations
- // that happen on their main UI thread.
- handleViolation(crashInfo, savedPolicy);
- } else {
- MessageQueue queue = Looper.myQueue();
- final long violationTime = SystemClock.uptimeMillis();
- queue.addIdleHandler(new MessageQueue.IdleHandler() {
- public boolean queueIdle() {
- long afterViolationTime = SystemClock.uptimeMillis();
- crashInfo.durationMillis = afterViolationTime - violationTime;
- handleViolation(crashInfo, savedPolicy);
- return false; // remove this idle handler from the array
- }
- });
+ info.durationMillis = -1; // unknown (redundant, already set)
+ handleViolation(info);
+ return;
}
+ MessageQueue queue = Looper.myQueue();
+ final ArrayList<ViolationInfo> records = violationsBeingTimed.get();
+ if (records.size() >= 10) {
+ // Not worth measuring. Too many offenses in one loop.
+ return;
+ }
+ records.add(info);
+ if (records.size() > 1) {
+ // There's already been a violation this loop, so we've already
+ // registered an idle handler to process the list of violations
+ // at the end of this Looper's loop.
+ return;
+ }
+
+ queue.addIdleHandler(new MessageQueue.IdleHandler() {
+ public boolean queueIdle() {
+ long loopFinishTime = SystemClock.uptimeMillis();
+ for (int n = 0; n < records.size(); ++n) {
+ ViolationInfo v = records.get(n);
+ v.violationNumThisLoop = n + 1;
+ v.durationMillis =
+ (int) (loopFinishTime - v.violationUptimeMillis);
+ handleViolation(v);
+ }
+ records.clear();
+ return false; // remove this idle handler from the array
+ }
+ });
}
// Note: It's possible (even quite likely) that the
@@ -301,37 +347,35 @@
// violation fired and now (after the violating code ran) due
// to people who push/pop temporary policy in regions of code,
// hence the policy being passed around.
- void handleViolation(
- final ApplicationErrorReport.CrashInfo crashInfo,
- int policy) {
- if (crashInfo.stackTrace == null) {
- Log.d(TAG, "unexpected null stacktrace");
+ void handleViolation(final ViolationInfo info) {
+ if (info == null || info.crashInfo == null || info.crashInfo.stackTrace == null) {
+ Log.wtf(TAG, "unexpected null stacktrace");
return;
}
- if (LOG_V) Log.d(TAG, "handleViolation; policy=" + policy);
+ if (LOG_V) Log.d(TAG, "handleViolation; policy=" + info.policy);
- if ((policy & PENALTY_GATHER) != 0) {
- ArrayList<ApplicationErrorReport.CrashInfo> violations = gatheredViolations.get();
+ if ((info.policy & PENALTY_GATHER) != 0) {
+ ArrayList<ViolationInfo> violations = gatheredViolations.get();
if (violations == null) {
- violations = new ArrayList<ApplicationErrorReport.CrashInfo>(1);
+ violations = new ArrayList<ViolationInfo>(1);
gatheredViolations.set(violations);
} else if (violations.size() >= 5) {
// Too many. In a loop or something? Don't gather them all.
return;
}
- for (ApplicationErrorReport.CrashInfo previous : violations) {
- if (crashInfo.stackTrace.equals(previous.stackTrace)) {
+ for (ViolationInfo previous : violations) {
+ if (info.crashInfo.stackTrace.equals(previous.crashInfo.stackTrace)) {
// Duplicate. Don't log.
return;
}
}
- violations.add(crashInfo);
+ violations.add(info);
return;
}
// Not perfect, but fast and good enough for dup suppression.
- Integer crashFingerprint = crashInfo.stackTrace.hashCode();
+ Integer crashFingerprint = info.crashInfo.stackTrace.hashCode();
long lastViolationTime = 0;
if (mLastViolationTime.containsKey(crashFingerprint)) {
lastViolationTime = mLastViolationTime.get(crashFingerprint);
@@ -341,13 +385,13 @@
long timeSinceLastViolationMillis = lastViolationTime == 0 ?
Long.MAX_VALUE : (now - lastViolationTime);
- if ((policy & PENALTY_LOG) != 0 &&
+ if ((info.policy & PENALTY_LOG) != 0 &&
timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
- if (crashInfo.durationMillis != -1) {
+ if (info.durationMillis != -1) {
Log.d(TAG, "StrictMode policy violation; ~duration=" +
- crashInfo.durationMillis + " ms: " + crashInfo.stackTrace);
+ info.durationMillis + " ms: " + info.crashInfo.stackTrace);
} else {
- Log.d(TAG, "StrictMode policy violation: " + crashInfo.stackTrace);
+ Log.d(TAG, "StrictMode policy violation: " + info.crashInfo.stackTrace);
}
}
@@ -355,20 +399,20 @@
// subset of the original StrictMode policy bitmask, with
// only the bit violated and penalty bits to be executed
// by the ActivityManagerService remaining set.
- int violationMask = 0;
+ int violationMaskSubset = 0;
- if ((policy & PENALTY_DIALOG) != 0 &&
+ if ((info.policy & PENALTY_DIALOG) != 0 &&
timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) {
- violationMask |= PENALTY_DIALOG;
+ violationMaskSubset |= PENALTY_DIALOG;
}
- if ((policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) {
- violationMask |= PENALTY_DROPBOX;
+ if ((info.policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) {
+ violationMaskSubset |= PENALTY_DROPBOX;
}
- if (violationMask != 0) {
- int violationBit = parseViolationFromMessage(crashInfo.exceptionMessage);
- violationMask |= violationBit;
+ if (violationMaskSubset != 0) {
+ int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage);
+ violationMaskSubset |= violationBit;
final int savedPolicy = getThreadBlockingPolicy();
try {
// First, remove any policy before we call into the Activity Manager,
@@ -379,8 +423,8 @@
ActivityManagerNative.getDefault().handleApplicationStrictModeViolation(
RuntimeInit.getApplicationObject(),
- violationMask,
- crashInfo);
+ violationMaskSubset,
+ info);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException trying to handle StrictMode violation", e);
} finally {
@@ -389,7 +433,7 @@
}
}
- if ((policy & PENALTY_DEATH) != 0) {
+ if ((info.policy & PENALTY_DEATH) != 0) {
System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down.");
Process.killProcess(Process.myPid());
System.exit(10);
@@ -417,7 +461,7 @@
* Called from Parcel.writeNoException()
*/
/* package */ static void writeGatheredViolationsToParcel(Parcel p) {
- ArrayList<ApplicationErrorReport.CrashInfo> violations = gatheredViolations.get();
+ ArrayList<ViolationInfo> violations = gatheredViolations.get();
if (violations == null) {
p.writeInt(0);
} else {
@@ -439,35 +483,21 @@
*/
/* package */ static void readAndHandleBinderCallViolations(Parcel p) {
// Our own stack trace to append
- Exception e = new LogStackTrace();
StringWriter sw = new StringWriter();
- e.printStackTrace(new PrintWriter(sw));
+ new LogStackTrace().printStackTrace(new PrintWriter(sw));
String ourStack = sw.toString();
int policyMask = getThreadBlockingPolicy();
+ boolean currentlyGathering = (policyMask & PENALTY_GATHER) != 0;
int numViolations = p.readInt();
for (int i = 0; i < numViolations; ++i) {
if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i);
- ApplicationErrorReport.CrashInfo crashInfo = new ApplicationErrorReport.CrashInfo(p);
- crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack;
-
- // Unlike the in-process violations in which case we
- // trigger an error _before_ the thing occurs, in this
- // case the violating thing has already occurred, so we
- // can't use our heuristic of waiting for the next event
- // loop idle cycle to measure the approximate violation
- // duration. Instead, just skip that step and use -1
- // (unknown duration) for now.
- // TODO: keep a thread-local on remote process of first
- // violation time's uptimeMillis, and when writing that
- // back out in Parcel reply, include in the header the
- // violation time and use it here.
- crashInfo.durationMillis = -1;
-
+ ViolationInfo info = new ViolationInfo(p, !currentlyGathering);
+ info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack;
BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
if (policy instanceof AndroidBlockGuardPolicy) {
- ((AndroidBlockGuardPolicy) policy).handleViolation(crashInfo, policyMask);
+ ((AndroidBlockGuardPolicy) policy).handleViolationWithTimingAttempt(info);
}
}
}
@@ -483,4 +513,113 @@
private static void onBinderStrictModePolicyChange(int newPolicy) {
setBlockGuardPolicy(newPolicy);
}
+
+ /**
+ * Parcelable that gets sent in Binder call headers back to callers
+ * to report violations that happened during a cross-process call.
+ *
+ * @hide
+ */
+ public static class ViolationInfo {
+ /**
+ * Stack and other stuff info.
+ */
+ public final ApplicationErrorReport.CrashInfo crashInfo;
+
+ /**
+ * The strict mode policy mask at the time of violation.
+ */
+ public final int policy;
+
+ /**
+ * The wall time duration of the violation, when known. -1 when
+ * not known.
+ */
+ public int durationMillis = -1;
+
+ /**
+ * Which violation number this was (1-based) since the last Looper loop,
+ * from the perspective of the root caller (if it crossed any processes
+ * via Binder calls). The value is 0 if the root caller wasn't on a Looper
+ * thread.
+ */
+ public int violationNumThisLoop;
+
+ /**
+ * The time (in terms of SystemClock.uptimeMillis()) that the
+ * violation occurred.
+ */
+ public long violationUptimeMillis;
+
+ /**
+ * Create an uninitialized instance of ViolationInfo
+ */
+ public ViolationInfo() {
+ crashInfo = null;
+ policy = 0;
+ }
+
+ /**
+ * Create an instance of ViolationInfo initialized from an exception.
+ */
+ public ViolationInfo(Throwable tr, int policy) {
+ crashInfo = new ApplicationErrorReport.CrashInfo(tr);
+ violationUptimeMillis = SystemClock.uptimeMillis();
+ this.policy = policy;
+ }
+
+ /**
+ * Create an instance of ViolationInfo initialized from a Parcel.
+ */
+ public ViolationInfo(Parcel in) {
+ this(in, false);
+ }
+
+ /**
+ * Create an instance of ViolationInfo initialized from a Parcel.
+ *
+ * @param unsetGatheringBit if true, the caller is the root caller
+ * and the gathering penalty should be removed.
+ */
+ public ViolationInfo(Parcel in, boolean unsetGatheringBit) {
+ crashInfo = new ApplicationErrorReport.CrashInfo(in);
+ int rawPolicy = in.readInt();
+ if (unsetGatheringBit) {
+ policy = rawPolicy & ~PENALTY_GATHER;
+ } else {
+ policy = rawPolicy;
+ }
+ durationMillis = in.readInt();
+ violationNumThisLoop = in.readInt();
+ violationUptimeMillis = in.readLong();
+ }
+
+ /**
+ * Save a ViolationInfo instance to a parcel.
+ */
+ public void writeToParcel(Parcel dest, int flags) {
+ crashInfo.writeToParcel(dest, flags);
+ dest.writeInt(policy);
+ dest.writeInt(durationMillis);
+ dest.writeInt(violationNumThisLoop);
+ dest.writeLong(violationUptimeMillis);
+ }
+
+
+ /**
+ * Dump a ViolationInfo instance to a Printer.
+ */
+ public void dump(Printer pw, String prefix) {
+ crashInfo.dump(pw, prefix);
+ pw.println(prefix + "policy: " + policy);
+ if (durationMillis != -1) {
+ pw.println(prefix + "durationMillis: " + durationMillis);
+ }
+ if (violationNumThisLoop != 0) {
+ pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop);
+ }
+ pw.println(prefix + "violationUptimeMillis: " + violationUptimeMillis);
+ }
+
+ }
}
diff --git a/core/java/android/widget/BaseExpandableListAdapter.java b/core/java/android/widget/BaseExpandableListAdapter.java
index 396b7ae..b4d6ad7 100644
--- a/core/java/android/widget/BaseExpandableListAdapter.java
+++ b/core/java/android/widget/BaseExpandableListAdapter.java
@@ -43,14 +43,14 @@
}
/**
- * {@see DataSetObservable#notifyInvalidated()}
+ * @see DataSetObservable#notifyInvalidated()
*/
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
/**
- * {@see DataSetObservable#notifyChanged()}
+ * @see DataSetObservable#notifyChanged()
*/
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
diff --git a/core/java/android/widget/HeterogeneousExpandableList.java b/core/java/android/widget/HeterogeneousExpandableList.java
index 1292733..e7e0933 100644
--- a/core/java/android/widget/HeterogeneousExpandableList.java
+++ b/core/java/android/widget/HeterogeneousExpandableList.java
@@ -23,12 +23,13 @@
* Additional methods that when implemented make an
* {@link ExpandableListAdapter} take advantage of the {@link Adapter} view type
* mechanism.
- *
- * An {@link ExpandableListAdapter} declares one view type for its group items
+ * <p>
+ * An {@link ExpandableListAdapter} declares it has one view type for its group items
* and one view type for its child items. Although adapted for most {@link ExpandableListView}s,
- * these values should be tuned heterogeneous {@link ExpandableListView}s. Lists that contain
- * different types of group and/or child item views, should use an adapter that implements this
- * interface. This way, the recycled views that will be provided to
+ * these values should be tuned for heterogeneous {@link ExpandableListView}s.
+ * </p>
+ * Lists that contain different types of group and/or child item views, should use an adapter that
+ * implements this interface. This way, the recycled views that will be provided to
* {@link android.widget.ExpandableListAdapter#getGroupView(int, boolean, View, ViewGroup)}
* and
* {@link android.widget.ExpandableListAdapter#getChildView(int, int, boolean, View, ViewGroup)}
@@ -48,7 +49,7 @@
* . Note: Integers must be in the range 0 to {@link #getGroupTypeCount} - 1.
* {@link android.widget.Adapter#IGNORE_ITEM_VIEW_TYPE} can also be returned.
* @see android.widget.Adapter#IGNORE_ITEM_VIEW_TYPE
- * @see getGroupTypeCount()
+ * @see #getGroupTypeCount()
*/
int getGroupType(int groupPosition);
@@ -65,7 +66,7 @@
* Note: Integers must be in the range 0 to {@link #getChildTypeCount} - 1.
* {@link android.widget.Adapter#IGNORE_ITEM_VIEW_TYPE} can also be returned.
* @see android.widget.Adapter#IGNORE_ITEM_VIEW_TYPE
- * @see getChildTypeCount()
+ * @see #getChildTypeCount()
*/
int getChildType(int groupPosition, int childPosition);
@@ -78,13 +79,11 @@
* . If the adapter always returns the same type of View for all group items, this method should
* return 1.
* </p>
- * <p>
* This method will only be called when the adapter is set on the {@link AdapterView}.
- * </p>
*
* @return The number of types of group Views that will be created by this adapter.
- * @see getChildTypeCount()
- * @see getGroupType()
+ * @see #getChildTypeCount()
+ * @see #getGroupType(int)
*/
int getGroupTypeCount();
@@ -97,13 +96,11 @@
* , for any group. If the adapter always returns the same type of View for
* all child items, this method should return 1.
* </p>
- * <p>
* This method will only be called when the adapter is set on the {@link AdapterView}.
- * </p>
*
* @return The total number of types of child Views that will be created by this adapter.
- * @see getGroupTypeCount()
- * @see getChildType()
+ * @see #getGroupTypeCount()
+ * @see #getChildType(int, int)
*/
int getChildTypeCount();
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index cdaefc8..ad8d444 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -91,30 +91,30 @@
// DISCONNECTING, DISCONNECTED, UNKNOWN
private void waitForNetworkState(int networkType, State expectedState, long timeout) {
long startTime = System.currentTimeMillis();
- // In case the broadcast is already sent out, no need to wait
- if (cmActivity.mCM.getNetworkInfo(networkType).getState() == expectedState) {
- return;
- } else {
- while (true) {
- if ((System.currentTimeMillis() - startTime) > timeout) {
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ if (cmActivity.mCM.getNetworkInfo(networkType).getState() != expectedState) {
assertFalse("Wait for network state timeout", true);
+ } else {
+ // the broadcast has been sent out. the state has been changed.
+ return;
}
- Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType +
- " to be " + expectedState.toString());
- synchronized (cmActivity.connectivityObject) {
- try {
- cmActivity.connectivityObject.wait(STATE_TRANSITION_SHORT_TIMEOUT);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if ((cmActivity.mNetworkInfo.getType() != networkType) ||
- (cmActivity.mNetworkInfo.getState() != expectedState)) {
- Log.v(LOG_TAG, "network state for " + cmActivity.mNetworkInfo.getType() +
- "is: " + cmActivity.mNetworkInfo.getState());
- continue;
- }
- break;
+ }
+ Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType +
+ " to be " + expectedState.toString());
+ synchronized (cmActivity.connectivityObject) {
+ try {
+ cmActivity.connectivityObject.wait(STATE_TRANSITION_SHORT_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
+ if ((cmActivity.mNetworkInfo.getType() != networkType) ||
+ (cmActivity.mNetworkInfo.getState() != expectedState)) {
+ Log.v(LOG_TAG, "network state for " + cmActivity.mNetworkInfo.getType() +
+ "is: " + cmActivity.mNetworkInfo.getState());
+ continue;
+ }
+ break;
}
}
}
@@ -123,26 +123,26 @@
// WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
private void waitForWifiState(int expectedState, long timeout) {
long startTime = System.currentTimeMillis();
- if (cmActivity.mWifiState == expectedState) {
- return;
- } else {
- while (true) {
- if ((System.currentTimeMillis() - startTime) > timeout) {
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ if (cmActivity.mWifiState != expectedState) {
assertFalse("Wait for Wifi state timeout", true);
+ } else {
+ return;
}
- Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState);
- synchronized (cmActivity.wifiObject) {
- try {
- cmActivity.wifiObject.wait(5*1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if (cmActivity.mWifiState != expectedState) {
- Log.v(LOG_TAG, "Wifi state is: " + cmActivity.mWifiNetworkInfo.getState());
- continue;
- }
- break;
+ }
+ Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState);
+ synchronized (cmActivity.wifiObject) {
+ try {
+ cmActivity.wifiObject.wait(5*1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
+ if (cmActivity.mWifiState != expectedState) {
+ Log.v(LOG_TAG, "Wifi state is: " + cmActivity.mWifiNetworkInfo.getState());
+ continue;
+ }
+ break;
}
}
}
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 7e2f8a0..1d6ab25 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -450,8 +450,8 @@
to match the device density.</li>
</ul>
<p><em>Added in API Level 4.</em></p>
- <p>There is thus a 4:3 scaling factor between each density, so a 9x9 bitmap
- in ldpi is 12x12 in mdpi and 16x16 in hdpi.</p>
+ <p>There is thus a 3:4:6 scaling ratio between the three densities, so a 9x9 bitmap
+ in ldpi is 12x12 in mdpi and 18x18 in hdpi.</p>
<p>When Android selects which resource files to use,
it handles screen density differently than the other qualifiers.
In step 1 of <a href="#BestMatch">How Android finds the best
@@ -895,7 +895,7 @@
drawable-port-notouch-12key/
</pre>
<p class="note"><strong>Exception:</strong> Screen pixel density is the one qualifier that is not
-eliminated due to a contradiction. Even though the screen density of the device is mdpi,
+eliminated due to a contradiction. Even though the screen density of the device is hdpi,
<code>drawable-port-ldpi/</code> is not eliminated because every screen density is
considered to be a match at this point. More information is available in the <a
href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
@@ -922,9 +922,8 @@
<strike>drawable-port-notouch-12key/</strike>
</pre>
<p class="note"><strong>Exception:</strong> If the qualifier in question is screen pixel density,
-Android
-selects the option that most closely matches the device, and the selection process is complete.
-In general, Android prefers scaling down a larger original image to scaling up a smaller
+Android selects the option that most closely matches the device screen density.
+In general, Android prefers scaling down a larger original image to scaling up a smaller
original image. See <a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
Screens</a>.</p>
</li>
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 9974f2f..964700b 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008 The Android Open Source Project
- * Copyright (C) 2008 HTC Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index cfc17a5..54adca8 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -1,6 +1,6 @@
/*
**
- ** Copyright 2008, HTC Inc.
+ ** Copyright 2008, 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.
diff --git a/include/media/PVMediaRecorder.h b/include/media/PVMediaRecorder.h
index f75d80d..c091c39 100644
--- a/include/media/PVMediaRecorder.h
+++ b/include/media/PVMediaRecorder.h
@@ -1,6 +1,6 @@
/*
**
- ** Copyright 2008, HTC Inc.
+ ** Copyright 2008, 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.
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index d7ec8ea..6bf1bfa 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -210,7 +210,7 @@
* IMPORTANT INVARIANT:
* Because the policy and dispatcher can potentially block or cause re-entrance into
* the input reader, the input reader never calls into other components while holding
- * an exclusive internal lock.
+ * an exclusive internal lock whenever re-entrance can happen.
*/
class InputReader : public InputReaderInterface, private InputReaderContext {
public:
@@ -414,6 +414,8 @@
virtual int32_t getMetaState();
private:
+ Mutex mLock;
+
struct KeyDown {
int32_t keyCode;
int32_t scanCode;
@@ -423,17 +425,22 @@
uint32_t mSources;
int32_t mKeyboardType;
- Vector<KeyDown> mKeyDowns; // keys that are down
- int32_t mMetaState;
- nsecs_t mDownTime; // time of most recent key down
+ struct LockedState {
+ Vector<KeyDown> keyDowns; // keys that are down
+ int32_t metaState;
+ nsecs_t downTime; // time of most recent key down
+ } mLocked;
- void initialize();
+ void initializeLocked();
bool isKeyboardOrGamepadKey(int32_t scanCode);
+
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 findKeyDown(int32_t scanCode);
+ ssize_t findKeyDownLocked(int32_t scanCode);
};
@@ -451,6 +458,8 @@
// Amount that trackball needs to move in order to generate a key event.
static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
+ Mutex mLock;
+
int32_t mAssociatedDisplayId;
struct Accumulator {
@@ -475,17 +484,21 @@
}
} mAccumulator;
- bool mDown;
- nsecs_t mDownTime;
-
float mXScale;
float mYScale;
float mXPrecision;
float mYPrecision;
- void initialize();
+ struct LockedState {
+ bool down;
+ nsecs_t downTime;
+ } mLocked;
+
+ void initializeLocked();
void sync(nsecs_t when);
+ void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+ PointerCoords* pointerCoords, nsecs_t downTime);
};
@@ -509,6 +522,8 @@
* (This is limited by our use of BitSet32 to track pointer assignments.) */
static const uint32_t MAX_POINTER_ID = 31;
+ Mutex mLock;
+
struct VirtualKey {
int32_t keyCode;
int32_t scanCode;
@@ -561,7 +576,6 @@
};
int32_t mAssociatedDisplayId;
- Vector<VirtualKey> mVirtualKeys;
// Immutable configuration parameters.
struct Parameters {
@@ -583,67 +597,65 @@
RawAbsoluteAxisInfo orientation;
} mAxes;
- // The surface orientation and width and height set by configureSurface().
- int32_t mSurfaceOrientation;
- int32_t mSurfaceWidth, mSurfaceHeight;
-
- // Translation and scaling factors, orientation-independent.
- int32_t mXOrigin;
- float mXScale;
- float mXPrecision;
-
- int32_t mYOrigin;
- float mYScale;
- float mYPrecision;
-
- int32_t mPressureOrigin;
- float mPressureScale;
-
- int32_t mSizeOrigin;
- float mSizeScale;
-
- float mOrientationScale;
-
- // Oriented motion ranges for input device info.
- struct OrientedRanges {
- InputDeviceInfo::MotionRange x;
- InputDeviceInfo::MotionRange y;
- InputDeviceInfo::MotionRange pressure;
- InputDeviceInfo::MotionRange size;
- InputDeviceInfo::MotionRange touchMajor;
- InputDeviceInfo::MotionRange touchMinor;
- InputDeviceInfo::MotionRange toolMajor;
- InputDeviceInfo::MotionRange toolMinor;
- InputDeviceInfo::MotionRange orientation;
- } mOrientedRanges;
-
- // Oriented dimensions and precision.
- float mOrientedSurfaceWidth, mOrientedSurfaceHeight;
- float mOrientedXPrecision, mOrientedYPrecision;
-
- // The touch data of the current sample being processed.
+ // Current and previous touch sample data.
TouchData mCurrentTouch;
-
- // The touch data of the previous sample that was processed. This is updated
- // incrementally while the current sample is being processed.
TouchData mLastTouch;
// The time the primary pointer last went down.
nsecs_t mDownTime;
- struct CurrentVirtualKeyState {
- bool down;
- nsecs_t downTime;
- int32_t keyCode;
- int32_t scanCode;
- } mCurrentVirtualKey;
+ struct LockedState {
+ Vector<VirtualKey> virtualKeys;
- // Lock for virtual key state.
- Mutex mVirtualKeyLock; // methods use "Lvk" suffix
+ // The surface orientation and width and height set by configureSurfaceLocked().
+ int32_t surfaceOrientation;
+ int32_t surfaceWidth, surfaceHeight;
+
+ // Translation and scaling factors, orientation-independent.
+ int32_t xOrigin;
+ float xScale;
+ float xPrecision;
+
+ int32_t yOrigin;
+ float yScale;
+ float yPrecision;
+
+ int32_t pressureOrigin;
+ float pressureScale;
+
+ int32_t sizeOrigin;
+ float sizeScale;
+
+ float orientationScale;
+
+ // Oriented motion ranges for input device info.
+ struct OrientedRanges {
+ InputDeviceInfo::MotionRange x;
+ InputDeviceInfo::MotionRange y;
+ InputDeviceInfo::MotionRange pressure;
+ InputDeviceInfo::MotionRange size;
+ InputDeviceInfo::MotionRange touchMajor;
+ InputDeviceInfo::MotionRange touchMinor;
+ InputDeviceInfo::MotionRange toolMajor;
+ InputDeviceInfo::MotionRange toolMinor;
+ InputDeviceInfo::MotionRange orientation;
+ } orientedRanges;
+
+ // Oriented dimensions and precision.
+ float orientedSurfaceWidth, orientedSurfaceHeight;
+ float orientedXPrecision, orientedYPrecision;
+
+ struct CurrentVirtualKeyState {
+ bool down;
+ nsecs_t downTime;
+ int32_t keyCode;
+ int32_t scanCode;
+ } currentVirtualKey;
+ } mLocked;
virtual void configureAxes();
- virtual bool configureSurface();
- virtual void configureVirtualKeys();
+ virtual bool configureSurfaceLocked();
+ virtual void configureVirtualKeysLocked();
enum TouchResult {
// Dispatch the touch normally.
@@ -696,15 +708,19 @@
uint64_t distance : 48; // squared distance
};
- void initialize();
+ void initializeLocked();
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
BitSet32 idBits, uint32_t changedId, int32_t motionEventAction);
- bool isPointInsideSurface(int32_t x, int32_t y);
- const VirtualKey* findVirtualKeyHitLvk(int32_t x, int32_t y);
+ 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);
bool applyBadTouchFilter();
bool applyJumpyTouchFilter();
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index 0037399..7efc6d7 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -1,7 +1,6 @@
/*
**
** Copyright (C) 2008, The Android Open Source Project
-** Copyright (C) 2008 HTC Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 56e2977..6618702 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -713,15 +713,15 @@
uint32_t sources, int32_t keyboardType) :
InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources),
mKeyboardType(keyboardType) {
- initialize();
+ initializeLocked();
}
KeyboardInputMapper::~KeyboardInputMapper() {
}
-void KeyboardInputMapper::initialize() {
- mMetaState = AMETA_NONE;
- mDownTime = 0;
+void KeyboardInputMapper::initializeLocked() {
+ mLocked.metaState = AMETA_NONE;
+ mLocked.downTime = 0;
}
uint32_t KeyboardInputMapper::getSources() {
@@ -735,17 +735,27 @@
}
void KeyboardInputMapper::reset() {
- // Synthesize key up event on reset if keys are currently down.
- while (! mKeyDowns.isEmpty()) {
- const KeyDown& keyDown = mKeyDowns.top();
+ for (;;) {
+ int32_t keyCode, scanCode;
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ // Synthesize key up event on reset if keys are currently down.
+ if (mLocked.keyDowns.isEmpty()) {
+ initializeLocked();
+ break; // done
+ }
+
+ const KeyDown& keyDown = mLocked.keyDowns.top();
+ keyCode = keyDown.keyCode;
+ scanCode = keyDown.scanCode;
+ } // release lock
+
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- processKey(when, false, keyDown.keyCode, keyDown.scanCode, 0);
+ processKey(when, false, keyCode, scanCode, 0);
}
InputMapper::reset();
-
- // Reinitialize.
- initialize();
getContext()->updateGlobalMetaState();
}
@@ -768,56 +778,76 @@
|| (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
}
-void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
- uint32_t policyFlags) {
- if (down) {
- // Rotate key codes according to orientation.
- if (mAssociatedDisplayId >= 0) {
- int32_t orientation;
- if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
- return;
+void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
+ int32_t scanCode, uint32_t policyFlags) {
+ int32_t newMetaState;
+ nsecs_t downTime;
+ bool metaStateChanged = false;
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (down) {
+ // Rotate key codes according to orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ if (mAssociatedDisplayId >= 0) {
+ int32_t orientation;
+ if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+ return;
+ }
+
+ keyCode = rotateKeyCode(keyCode, orientation);
}
- keyCode = rotateKeyCode(keyCode, orientation);
+ // Add key down.
+ ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+ if (keyDownIndex >= 0) {
+ // key repeat, be sure to use same keycode as before in case of rotation
+ keyCode = mLocked.keyDowns.top().keyCode;
+ } else {
+ // key down
+ mLocked.keyDowns.push();
+ KeyDown& keyDown = mLocked.keyDowns.editTop();
+ keyDown.keyCode = keyCode;
+ keyDown.scanCode = scanCode;
+ }
+
+ mLocked.downTime = when;
+ } else {
+ // Remove key down.
+ ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+ if (keyDownIndex >= 0) {
+ // key up, be sure to use same keycode as before in case of rotation
+ keyCode = mLocked.keyDowns.top().keyCode;
+ mLocked.keyDowns.removeAt(size_t(keyDownIndex));
+ } else {
+ // key was not actually down
+ LOGI("Dropping key up from device %s because the key was not down. "
+ "keyCode=%d, scanCode=%d",
+ getDeviceName().string(), keyCode, scanCode);
+ return;
+ }
}
- // Add key down.
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
- // key repeat, be sure to use same keycode as before in case of rotation
- keyCode = mKeyDowns.top().keyCode;
- } else {
- // key down
- mKeyDowns.push();
- KeyDown& keyDown = mKeyDowns.editTop();
- keyDown.keyCode = keyCode;
- keyDown.scanCode = scanCode;
+ int32_t oldMetaState = mLocked.metaState;
+ newMetaState = updateMetaState(keyCode, down, oldMetaState);
+ if (oldMetaState != newMetaState) {
+ mLocked.metaState = newMetaState;
+ metaStateChanged = true;
}
- } else {
- // Remove key down.
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
- // key up, be sure to use same keycode as before in case of rotation
- keyCode = mKeyDowns.top().keyCode;
- mKeyDowns.removeAt(size_t(keyDownIndex));
- } else {
- // key was not actually down
- LOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
- return;
- }
- }
- int32_t oldMetaState = mMetaState;
- int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
- if (oldMetaState != newMetaState) {
- mMetaState = newMetaState;
+ downTime = mLocked.downTime;
+ } // release lock
+
+ if (metaStateChanged) {
getContext()->updateGlobalMetaState();
}
- /* Apply policy. */
+ 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);
@@ -825,30 +855,20 @@
return; // event dropped
}
- /* Enqueue key event for dispatch. */
-
- int32_t keyEventAction;
- if (down) {
- mDownTime = when;
- keyEventAction = AKEY_EVENT_ACTION_DOWN;
- } else {
- keyEventAction = AKEY_EVENT_ACTION_UP;
- }
-
+ 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 = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE;
}
getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode,
- mMetaState, mDownTime);
+ keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
}
-ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
- size_t n = mKeyDowns.size();
+ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
+ size_t n = mLocked.keyDowns.size();
for (size_t i = 0; i < n; i++) {
- if (mKeyDowns[i].scanCode == scanCode) {
+ if (mLocked.keyDowns[i].scanCode == scanCode) {
return i;
}
}
@@ -869,7 +889,10 @@
}
int32_t KeyboardInputMapper::getMetaState() {
- return mMetaState;
+ { // acquire lock
+ AutoMutex _l(mLock);
+ return mLocked.metaState;
+ } // release lock
}
@@ -882,7 +905,7 @@
mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
- initialize();
+ initializeLocked();
}
TrackballInputMapper::~TrackballInputMapper() {
@@ -899,26 +922,33 @@
info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
}
-void TrackballInputMapper::initialize() {
+void TrackballInputMapper::initializeLocked() {
mAccumulator.clear();
- mDown = false;
- mDownTime = 0;
+ mLocked.down = false;
+ mLocked.downTime = 0;
}
void TrackballInputMapper::reset() {
- // Synthesize trackball button up event on reset if trackball button is currently down.
- if (mDown) {
+ for (;;) {
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (! mLocked.down) {
+ initializeLocked();
+ break; // done
+ }
+ } // release lock
+
+ // Synthesize trackball button up event on reset.
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
+ mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
mAccumulator.btnMouse = false;
sync(when);
+ mAccumulator.clear();
}
InputMapper::reset();
-
- // Reinitialize.
- initialize();
}
void TrackballInputMapper::process(const RawEvent* rawEvent) {
@@ -962,33 +992,79 @@
}
void TrackballInputMapper::sync(nsecs_t when) {
- /* Get display properties so for rotation based on display orientation. */
+ int motionEventAction;
+ PointerCoords pointerCoords;
+ nsecs_t downTime;
+ { // acquire lock
+ AutoMutex _l(mLock);
- int32_t orientation;
- if (mAssociatedDisplayId >= 0) {
- if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
- return;
+ uint32_t fields = mAccumulator.fields;
+ bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
+
+ if (downChanged) {
+ if (mAccumulator.btnMouse) {
+ mLocked.down = true;
+ mLocked.downTime = when;
+ } else {
+ mLocked.down = false;
+ }
}
- } else {
- orientation = InputReaderPolicyInterface::ROTATION_0;
- }
- /* Update saved trackball state */
+ downTime = mLocked.downTime;
+ float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
+ float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
- uint32_t fields = mAccumulator.fields;
- bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
-
- if (downChanged) {
- if (mAccumulator.btnMouse) {
- mDown = true;
- mDownTime = when;
+ if (downChanged) {
+ motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
} else {
- mDown = false;
+ motionEventAction = AMOTION_EVENT_ACTION_MOVE;
}
- }
- /* Apply policy */
+ pointerCoords.x = x;
+ pointerCoords.y = y;
+ pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
+ pointerCoords.size = 0;
+ pointerCoords.touchMajor = 0;
+ pointerCoords.touchMinor = 0;
+ pointerCoords.toolMajor = 0;
+ pointerCoords.toolMinor = 0;
+ pointerCoords.orientation = 0;
+ if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) {
+ // Rotate motion based on display orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ int32_t orientation;
+ if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+ return;
+ }
+
+ float temp;
+ switch (orientation) {
+ case InputReaderPolicyInterface::ROTATION_90:
+ temp = pointerCoords.x;
+ pointerCoords.x = pointerCoords.y;
+ pointerCoords.y = - temp;
+ break;
+
+ case InputReaderPolicyInterface::ROTATION_180:
+ pointerCoords.x = - pointerCoords.x;
+ pointerCoords.y = - pointerCoords.y;
+ break;
+
+ case InputReaderPolicyInterface::ROTATION_270:
+ temp = pointerCoords.x;
+ pointerCoords.x = - pointerCoords.y;
+ pointerCoords.y = temp;
+ break;
+ }
+ }
+ } // release lock
+
+ applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);
+}
+
+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);
@@ -996,62 +1072,24 @@
return; // event dropped
}
- /* Enqueue motion event for dispatch. */
-
- int32_t motionEventAction;
- if (downChanged) {
- motionEventAction = mDown ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else {
- motionEventAction = AMOTION_EVENT_ACTION_MOVE;
- }
-
- int32_t pointerId = 0;
- PointerCoords pointerCoords;
- pointerCoords.x = fields & Accumulator::FIELD_REL_X
- ? mAccumulator.relX * mXScale : 0;
- pointerCoords.y = fields & Accumulator::FIELD_REL_Y
- ? mAccumulator.relY * mYScale : 0;
- pointerCoords.pressure = 1.0f; // XXX Consider making this 1.0f if down, 0 otherwise.
- pointerCoords.size = 0;
- pointerCoords.touchMajor = 0;
- pointerCoords.touchMinor = 0;
- pointerCoords.toolMajor = 0;
- pointerCoords.toolMinor = 0;
- pointerCoords.orientation = 0;
-
- float temp;
- switch (orientation) {
- case InputReaderPolicyInterface::ROTATION_90:
- temp = pointerCoords.x;
- pointerCoords.x = pointerCoords.y;
- pointerCoords.y = - temp;
- break;
-
- case InputReaderPolicyInterface::ROTATION_180:
- pointerCoords.x = - pointerCoords.x;
- pointerCoords.y = - pointerCoords.y;
- break;
-
- case InputReaderPolicyInterface::ROTATION_270:
- temp = pointerCoords.x;
- pointerCoords.x = - pointerCoords.y;
- pointerCoords.y = temp;
- break;
- }
-
int32_t metaState = mContext->getGlobalMetaState();
+ int32_t pointerId = 0;
+
getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags,
motionEventAction, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, & pointerId, & pointerCoords, mXPrecision, mYPrecision, mDownTime);
+ 1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime);
}
// --- TouchInputMapper ---
TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
- InputMapper(device), mAssociatedDisplayId(associatedDisplayId),
- mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
- initialize();
+ InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
+ mLocked.surfaceOrientation = -1;
+ mLocked.surfaceWidth = -1;
+ mLocked.surfaceHeight = -1;
+
+ initializeLocked();
}
TouchInputMapper::~TouchInputMapper() {
@@ -1064,26 +1102,29 @@
void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- // FIXME: Should ensure the surface information is up to date so that orientation changes
- // are noticed immediately. Unfortunately we will need to add some extra locks here
- // to prevent race conditions.
- // configureSurface();
+ { // acquire lock
+ AutoMutex _l(mLock);
- info->addMotionRange(AINPUT_MOTION_RANGE_X, mOrientedRanges.x);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, mOrientedRanges.y);
- info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mOrientedRanges.pressure);
- info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mOrientedRanges.size);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mOrientedRanges.touchMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mOrientedRanges.touchMinor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mOrientedRanges.toolMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mOrientedRanges.toolMinor);
- info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mOrientedRanges.orientation);
+ // Ensure surface information is up to date so that orientation changes are
+ // noticed immediately.
+ configureSurfaceLocked();
+
+ info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
+ info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
+ info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mLocked.orientedRanges.pressure);
+ info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mLocked.orientedRanges.size);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mLocked.orientedRanges.touchMajor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mLocked.orientedRanges.touchMinor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mLocked.orientedRanges.toolMajor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mLocked.orientedRanges.toolMinor);
+ info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mLocked.orientedRanges.orientation);
+ } // release lock
}
-void TouchInputMapper::initialize() {
+void TouchInputMapper::initializeLocked() {
+ mCurrentTouch.clear();
mLastTouch.clear();
mDownTime = 0;
- mCurrentVirtualKey.down = false;
for (uint32_t i = 0; i < MAX_POINTERS; i++) {
mAveragingTouchFilter.historyStart[i] = 0;
@@ -1091,6 +1132,8 @@
}
mJumpyTouchFilter.jumpyPointsDropped = 0;
+
+ mLocked.currentVirtualKey.down = false;
}
void TouchInputMapper::configure() {
@@ -1104,48 +1147,52 @@
// Configure absolute axis information.
configureAxes();
- // Configure pressure factors.
- if (mAxes.pressure.valid) {
- mPressureOrigin = mAxes.pressure.minValue;
- mPressureScale = 1.0f / mAxes.pressure.getRange();
- } else {
- mPressureOrigin = 0;
- mPressureScale = 1.0f;
- }
+ { // acquire lock
+ AutoMutex _l(mLock);
- mOrientedRanges.pressure.min = 0.0f;
- mOrientedRanges.pressure.max = 1.0f;
- mOrientedRanges.pressure.flat = 0.0f;
- mOrientedRanges.pressure.fuzz = mPressureScale;
+ // Configure pressure factors.
+ if (mAxes.pressure.valid) {
+ mLocked.pressureOrigin = mAxes.pressure.minValue;
+ mLocked.pressureScale = 1.0f / mAxes.pressure.getRange();
+ } else {
+ mLocked.pressureOrigin = 0;
+ mLocked.pressureScale = 1.0f;
+ }
- // Configure size factors.
- if (mAxes.size.valid) {
- mSizeOrigin = mAxes.size.minValue;
- mSizeScale = 1.0f / mAxes.size.getRange();
- } else {
- mSizeOrigin = 0;
- mSizeScale = 1.0f;
- }
+ mLocked.orientedRanges.pressure.min = 0.0f;
+ mLocked.orientedRanges.pressure.max = 1.0f;
+ mLocked.orientedRanges.pressure.flat = 0.0f;
+ mLocked.orientedRanges.pressure.fuzz = mLocked.pressureScale;
- mOrientedRanges.size.min = 0.0f;
- mOrientedRanges.size.max = 1.0f;
- mOrientedRanges.size.flat = 0.0f;
- mOrientedRanges.size.fuzz = mSizeScale;
+ // Configure size factors.
+ if (mAxes.size.valid) {
+ mLocked.sizeOrigin = mAxes.size.minValue;
+ mLocked.sizeScale = 1.0f / mAxes.size.getRange();
+ } else {
+ mLocked.sizeOrigin = 0;
+ mLocked.sizeScale = 1.0f;
+ }
- // Configure orientation factors.
- if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
- mOrientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
- } else {
- mOrientationScale = 0.0f;
- }
+ mLocked.orientedRanges.size.min = 0.0f;
+ mLocked.orientedRanges.size.max = 1.0f;
+ mLocked.orientedRanges.size.flat = 0.0f;
+ mLocked.orientedRanges.size.fuzz = mLocked.sizeScale;
- mOrientedRanges.orientation.min = - M_PI_2;
- mOrientedRanges.orientation.max = M_PI_2;
- mOrientedRanges.orientation.flat = 0;
- mOrientedRanges.orientation.fuzz = mOrientationScale;
+ // Configure orientation factors.
+ if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
+ mLocked.orientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
+ } else {
+ mLocked.orientationScale = 0.0f;
+ }
- // Configure surface dimensions and orientation.
- configureSurface();
+ mLocked.orientedRanges.orientation.min = - M_PI_2;
+ mLocked.orientedRanges.orientation.max = M_PI_2;
+ mLocked.orientedRanges.orientation.flat = 0;
+ mLocked.orientedRanges.orientation.fuzz = mLocked.orientationScale;
+
+ // Configure surface dimensions and orientation.
+ configureSurfaceLocked();
+ } // release lock
}
void TouchInputMapper::configureAxes() {
@@ -1160,11 +1207,12 @@
mAxes.orientation.valid = false;
}
-bool TouchInputMapper::configureSurface() {
+bool TouchInputMapper::configureSurfaceLocked() {
// Update orientation and dimensions if needed.
int32_t orientation;
int32_t width, height;
if (mAssociatedDisplayId >= 0) {
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) {
return false;
}
@@ -1174,150 +1222,152 @@
height = mAxes.y.getRange();
}
- bool orientationChanged = mSurfaceOrientation != orientation;
+ bool orientationChanged = mLocked.surfaceOrientation != orientation;
if (orientationChanged) {
- mSurfaceOrientation = orientation;
+ mLocked.surfaceOrientation = orientation;
}
- bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
+ bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
if (sizeChanged) {
- mSurfaceWidth = width;
- mSurfaceHeight = height;
+ mLocked.surfaceWidth = width;
+ mLocked.surfaceHeight = height;
// Compute size-dependent translation and scaling factors and place virtual keys.
if (mAxes.x.valid && mAxes.y.valid) {
- mXOrigin = mAxes.x.minValue;
- mYOrigin = mAxes.y.minValue;
+ mLocked.xOrigin = mAxes.x.minValue;
+ mLocked.yOrigin = mAxes.y.minValue;
LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
getDeviceId(), getDeviceName().string());
- mXScale = float(width) / mAxes.x.getRange();
- mYScale = float(height) / mAxes.y.getRange();
- mXPrecision = 1.0f / mXScale;
- mYPrecision = 1.0f / mYScale;
+ mLocked.xScale = float(width) / mAxes.x.getRange();
+ mLocked.yScale = float(height) / mAxes.y.getRange();
+ mLocked.xPrecision = 1.0f / mLocked.xScale;
+ mLocked.yPrecision = 1.0f / mLocked.yScale;
- configureVirtualKeys();
+ configureVirtualKeysLocked();
} else {
- mXOrigin = 0;
- mYOrigin = 0;
- mXScale = 1.0f;
- mYScale = 1.0f;
- mXPrecision = 1.0f;
- mYPrecision = 1.0f;
+ mLocked.xOrigin = 0;
+ mLocked.yOrigin = 0;
+ mLocked.xScale = 1.0f;
+ mLocked.yScale = 1.0f;
+ mLocked.xPrecision = 1.0f;
+ mLocked.yPrecision = 1.0f;
}
// Configure touch and tool area ranges.
float diagonal = sqrt(float(width * width + height * height));
- float diagonalFuzz = sqrt(mXScale * mXScale + mYScale * mYScale);
+ float diagonalFuzz = sqrt(mLocked.xScale * mLocked.xScale
+ + mLocked.yScale * mLocked.yScale);
- mOrientedRanges.touchMajor.min = 0.0f;
- mOrientedRanges.touchMajor.max = diagonal;
- mOrientedRanges.touchMajor.flat = 0.0f;
- mOrientedRanges.touchMajor.fuzz = diagonalFuzz;
- mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
+ InputDeviceInfo::MotionRange area;
+ area.min = 0.0f;
+ area.max = diagonal;
+ area.flat = 0.0f;
+ area.fuzz = diagonalFuzz;
- mOrientedRanges.toolMinor = mOrientedRanges.toolMajor = mOrientedRanges.touchMajor;
+ mLocked.orientedRanges.touchMajor = area;
+ mLocked.orientedRanges.touchMinor = area;
+
+ mLocked.orientedRanges.toolMajor = area;
+ mLocked.orientedRanges.toolMinor = area;
}
if (orientationChanged || sizeChanged) {
// Compute oriented surface dimensions, precision, and scales.
float orientedXScale, orientedYScale;
- switch (mSurfaceOrientation) {
+ switch (mLocked.surfaceOrientation) {
case InputReaderPolicyInterface::ROTATION_90:
case InputReaderPolicyInterface::ROTATION_270:
- mOrientedSurfaceWidth = mSurfaceHeight;
- mOrientedSurfaceHeight = mSurfaceWidth;
- mOrientedXPrecision = mYPrecision;
- mOrientedYPrecision = mXPrecision;
- orientedXScale = mYScale;
- orientedYScale = mXScale;
+ mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
+ mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
+ mLocked.orientedXPrecision = mLocked.yPrecision;
+ mLocked.orientedYPrecision = mLocked.xPrecision;
+ orientedXScale = mLocked.yScale;
+ orientedYScale = mLocked.xScale;
break;
default:
- mOrientedSurfaceWidth = mSurfaceWidth;
- mOrientedSurfaceHeight = mSurfaceHeight;
- mOrientedXPrecision = mXPrecision;
- mOrientedYPrecision = mYPrecision;
- orientedXScale = mXScale;
- orientedYScale = mYScale;
+ mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
+ mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
+ mLocked.orientedXPrecision = mLocked.xPrecision;
+ mLocked.orientedYPrecision = mLocked.yPrecision;
+ orientedXScale = mLocked.xScale;
+ orientedYScale = mLocked.yScale;
break;
}
// Configure position ranges.
- mOrientedRanges.x.min = 0;
- mOrientedRanges.x.max = mOrientedSurfaceWidth;
- mOrientedRanges.x.flat = 0;
- mOrientedRanges.x.fuzz = orientedXScale;
+ mLocked.orientedRanges.x.min = 0;
+ mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth;
+ mLocked.orientedRanges.x.flat = 0;
+ mLocked.orientedRanges.x.fuzz = orientedXScale;
- mOrientedRanges.y.min = 0;
- mOrientedRanges.y.max = mOrientedSurfaceHeight;
- mOrientedRanges.y.flat = 0;
- mOrientedRanges.y.fuzz = orientedYScale;
+ mLocked.orientedRanges.y.min = 0;
+ mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight;
+ mLocked.orientedRanges.y.flat = 0;
+ mLocked.orientedRanges.y.fuzz = orientedYScale;
}
return true;
}
-void TouchInputMapper::configureVirtualKeys() {
+void TouchInputMapper::configureVirtualKeysLocked() {
assert(mAxes.x.valid && mAxes.y.valid);
+ // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
Vector<InputReaderPolicyInterface::VirtualKeyDefinition> virtualKeyDefinitions;
getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ mLocked.virtualKeys.clear();
- mVirtualKeys.clear();
+ if (virtualKeyDefinitions.size() == 0) {
+ return;
+ }
- if (virtualKeyDefinitions.size() == 0) {
- return;
+ mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+
+ int32_t touchScreenLeft = mAxes.x.minValue;
+ int32_t touchScreenTop = mAxes.y.minValue;
+ int32_t touchScreenWidth = mAxes.x.getRange();
+ int32_t touchScreenHeight = mAxes.y.getRange();
+
+ for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
+ const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
+ virtualKeyDefinitions[i];
+
+ mLocked.virtualKeys.add();
+ VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
+
+ virtualKey.scanCode = virtualKeyDefinition.scanCode;
+ int32_t keyCode;
+ uint32_t flags;
+ if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
+ & keyCode, & flags)) {
+ LOGW(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
+ mLocked.virtualKeys.pop(); // drop the key
+ continue;
}
- mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
+ virtualKey.keyCode = keyCode;
+ virtualKey.flags = flags;
- int32_t touchScreenLeft = mAxes.x.minValue;
- int32_t touchScreenTop = mAxes.y.minValue;
- int32_t touchScreenWidth = mAxes.x.getRange();
- int32_t touchScreenHeight = mAxes.y.getRange();
+ // convert the key definition's display coordinates into touch coordinates for a hit box
+ int32_t halfWidth = virtualKeyDefinition.width / 2;
+ int32_t halfHeight = virtualKeyDefinition.height / 2;
- for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
- const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
- virtualKeyDefinitions[i];
+ virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
+ * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
+ * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
+ * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
+ * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
- mVirtualKeys.add();
- VirtualKey& virtualKey = mVirtualKeys.editTop();
-
- virtualKey.scanCode = virtualKeyDefinition.scanCode;
- int32_t keyCode;
- uint32_t flags;
- if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
- & keyCode, & flags)) {
- LOGW(" VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
- mVirtualKeys.pop(); // drop the key
- continue;
- }
-
- virtualKey.keyCode = keyCode;
- virtualKey.flags = flags;
-
- // convert the key definition's display coordinates into touch coordinates for a hit box
- int32_t halfWidth = virtualKeyDefinition.width / 2;
- int32_t halfHeight = virtualKeyDefinition.height / 2;
-
- virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
- * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
- virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
- * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
- virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
- * touchScreenHeight / mSurfaceHeight + touchScreenTop;
- virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
- * touchScreenHeight / mSurfaceHeight + touchScreenTop;
-
- LOGI(" VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
- virtualKey.scanCode, virtualKey.keyCode,
- virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
- }
- } // release virtual key lock
+ LOGI(" VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+ virtualKey.scanCode, virtualKey.keyCode,
+ virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
+ }
}
void TouchInputMapper::reset() {
@@ -1329,20 +1379,16 @@
syncTouch(when, true);
}
- InputMapper::reset();
+ { // acquire lock
+ AutoMutex _l(mLock);
+ initializeLocked();
+ } // release lock
- // Reinitialize.
- initialize();
+ InputMapper::reset();
}
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
- /* Refresh associated display information and update our size configuration if needed. */
-
- if (! configureSurface()) {
- return;
- }
-
- /* Apply policy */
+ // Apply generic policy actions.
uint32_t policyFlags = 0;
int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
@@ -1352,7 +1398,7 @@
return; // event dropped
}
- /* Preprocess pointer data */
+ // Preprocess pointer data.
if (mParameters.useBadTouchFilter) {
if (applyBadTouchFilter()) {
@@ -1381,14 +1427,14 @@
savedTouch = & mCurrentTouch;
}
- /* Process touches and virtual keys */
+ // Process touches and virtual keys.
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
if (touchResult == DISPATCH_TOUCH) {
dispatchTouches(when, policyFlags);
}
- /* Copy current touch to last touch in preparation for the next cycle. */
+ // Copy current touch to last touch in preparation for the next cycle.
if (touchResult == DROP_STROKE) {
mLastTouch.clear();
@@ -1403,13 +1449,19 @@
int32_t keyCode, scanCode, downTime;
TouchResult touchResult;
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- if (mCurrentVirtualKey.down) {
+ // Update surface size and orientation, including virtual key positions.
+ if (! configureSurfaceLocked()) {
+ return DROP_STROKE;
+ }
+
+ // Check for virtual key press.
+ if (mLocked.currentVirtualKey.down) {
if (mCurrentTouch.pointerCount == 0) {
// Pointer went up while virtual key was down.
- mCurrentVirtualKey.down = false;
+ mLocked.currentVirtualKey.down = false;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1423,8 +1475,8 @@
if (mCurrentTouch.pointerCount == 1) {
int32_t x = mCurrentTouch.pointers[0].x;
int32_t y = mCurrentTouch.pointers[0].y;
- const VirtualKey* virtualKey = findVirtualKeyHitLvk(x, y);
- if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
+ const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
+ if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
// Pointer is still within the space of the virtual key.
return SKIP_TOUCH;
}
@@ -1434,7 +1486,7 @@
// Send key cancellation and drop the stroke so subsequent motions will be
// considered fresh downs. This is useful when the user swipes away from the
// virtual key area into the main display surface.
- mCurrentVirtualKey.down = false;
+ mLocked.currentVirtualKey.down = false;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1449,16 +1501,16 @@
// Pointer just went down. Handle off-screen touches, if needed.
int32_t x = mCurrentTouch.pointers[0].x;
int32_t y = mCurrentTouch.pointers[0].y;
- if (! isPointInsideSurface(x, y)) {
+ if (! isPointInsideSurfaceLocked(x, y)) {
// If exactly one pointer went down, check for virtual key hit.
// Otherwise we will drop the entire stroke.
if (mCurrentTouch.pointerCount == 1) {
- const VirtualKey* virtualKey = findVirtualKeyHitLvk(x, y);
+ const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
if (virtualKey) {
- mCurrentVirtualKey.down = true;
- mCurrentVirtualKey.downTime = when;
- mCurrentVirtualKey.keyCode = virtualKey->keyCode;
- mCurrentVirtualKey.scanCode = virtualKey->scanCode;
+ mLocked.currentVirtualKey.down = true;
+ mLocked.currentVirtualKey.downTime = when;
+ mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
+ mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1478,12 +1530,20 @@
DispatchVirtualKey:
// Collect remaining state needed to dispatch virtual key.
- keyCode = mCurrentVirtualKey.keyCode;
- scanCode = mCurrentVirtualKey.scanCode;
- downTime = mCurrentVirtualKey.downTime;
- } // release virtual key lock
+ keyCode = mLocked.currentVirtualKey.keyCode;
+ scanCode = mLocked.currentVirtualKey.scanCode;
+ downTime = mLocked.currentVirtualKey.downTime;
+ } // 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();
if (keyEventAction == AKEY_EVENT_ACTION_DOWN) {
@@ -1497,7 +1557,6 @@
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) {
@@ -1566,107 +1625,118 @@
uint32_t pointerCount = 0;
int32_t pointerIds[MAX_POINTERS];
PointerCoords pointerCoords[MAX_POINTERS];
-
- // Walk through the the active pointers and map touch screen coordinates (TouchData) into
- // display coordinates (PointerCoords) and adjust for display orientation.
- while (! idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
- uint32_t index = touch->idToIndex[id];
-
- float x = float(touch->pointers[index].x - mXOrigin) * mXScale;
- float y = float(touch->pointers[index].y - mYOrigin) * mYScale;
- float pressure = float(touch->pointers[index].pressure - mPressureOrigin) * mPressureScale;
- float size = float(touch->pointers[index].size - mSizeOrigin) * mSizeScale;
-
- float orientation = float(touch->pointers[index].orientation) * mOrientationScale;
-
- float touchMajor, touchMinor, toolMajor, toolMinor;
- if (abs(orientation) <= M_PI_4) {
- // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
- touchMajor = float(touch->pointers[index].touchMajor) * mYScale;
- touchMinor = float(touch->pointers[index].touchMinor) * mXScale;
- toolMajor = float(touch->pointers[index].toolMajor) * mYScale;
- toolMinor = float(touch->pointers[index].toolMinor) * mXScale;
- } else {
- // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
- touchMajor = float(touch->pointers[index].touchMajor) * mXScale;
- touchMinor = float(touch->pointers[index].touchMinor) * mYScale;
- toolMajor = float(touch->pointers[index].toolMajor) * mXScale;
- toolMinor = float(touch->pointers[index].toolMinor) * mYScale;
- }
-
- switch (mSurfaceOrientation) {
- case InputReaderPolicyInterface::ROTATION_90: {
- float xTemp = x;
- x = y;
- y = mSurfaceWidth - xTemp;
- orientation -= M_PI_2;
- if (orientation < - M_PI_2) {
- orientation += M_PI;
- }
- break;
- }
- case InputReaderPolicyInterface::ROTATION_180: {
- x = mSurfaceWidth - x;
- y = mSurfaceHeight - y;
- orientation = - orientation;
- break;
- }
- case InputReaderPolicyInterface::ROTATION_270: {
- float xTemp = x;
- x = mSurfaceHeight - y;
- y = xTemp;
- orientation += M_PI_2;
- if (orientation > M_PI_2) {
- orientation -= M_PI;
- }
- break;
- }
- }
-
- pointerIds[pointerCount] = int32_t(id);
-
- pointerCoords[pointerCount].x = x;
- pointerCoords[pointerCount].y = y;
- pointerCoords[pointerCount].pressure = pressure;
- pointerCoords[pointerCount].size = size;
- pointerCoords[pointerCount].touchMajor = touchMajor;
- pointerCoords[pointerCount].touchMinor = touchMinor;
- pointerCoords[pointerCount].toolMajor = toolMajor;
- pointerCoords[pointerCount].toolMinor = toolMinor;
- pointerCoords[pointerCount].orientation = orientation;
-
- if (id == changedId) {
- motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- }
-
- pointerCount += 1;
- }
-
- // Check edge flags by looking only at the first pointer since the flags are
- // global to the event.
int32_t motionEventEdgeFlags = 0;
- if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
- if (pointerCoords[0].x <= 0) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
- } else if (pointerCoords[0].x >= mOrientedSurfaceWidth) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+ float xPrecision, yPrecision;
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ // Walk through the the active pointers and map touch screen coordinates (TouchData) into
+ // display coordinates (PointerCoords) and adjust for display orientation.
+ while (! idBits.isEmpty()) {
+ uint32_t id = idBits.firstMarkedBit();
+ idBits.clearBit(id);
+ uint32_t index = touch->idToIndex[id];
+
+ float x = float(touch->pointers[index].x - mLocked.xOrigin) * mLocked.xScale;
+ float y = float(touch->pointers[index].y - mLocked.yOrigin) * mLocked.yScale;
+ float pressure = float(touch->pointers[index].pressure - mLocked.pressureOrigin)
+ * mLocked.pressureScale;
+ float size = float(touch->pointers[index].size - mLocked.sizeOrigin)
+ * mLocked.sizeScale;
+
+ float orientation = float(touch->pointers[index].orientation)
+ * mLocked.orientationScale;
+
+ float touchMajor, touchMinor, toolMajor, toolMinor;
+ if (abs(orientation) <= M_PI_4) {
+ // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
+ touchMajor = float(touch->pointers[index].touchMajor) * mLocked.yScale;
+ touchMinor = float(touch->pointers[index].touchMinor) * mLocked.xScale;
+ toolMajor = float(touch->pointers[index].toolMajor) * mLocked.yScale;
+ toolMinor = float(touch->pointers[index].toolMinor) * mLocked.xScale;
+ } else {
+ // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
+ touchMajor = float(touch->pointers[index].touchMajor) * mLocked.xScale;
+ touchMinor = float(touch->pointers[index].touchMinor) * mLocked.yScale;
+ toolMajor = float(touch->pointers[index].toolMajor) * mLocked.xScale;
+ toolMinor = float(touch->pointers[index].toolMinor) * mLocked.yScale;
+ }
+
+ switch (mLocked.surfaceOrientation) {
+ case InputReaderPolicyInterface::ROTATION_90: {
+ float xTemp = x;
+ x = y;
+ y = mLocked.surfaceWidth - xTemp;
+ orientation -= M_PI_2;
+ if (orientation < - M_PI_2) {
+ orientation += M_PI;
+ }
+ break;
+ }
+ case InputReaderPolicyInterface::ROTATION_180: {
+ x = mLocked.surfaceWidth - x;
+ y = mLocked.surfaceHeight - y;
+ orientation = - orientation;
+ break;
+ }
+ case InputReaderPolicyInterface::ROTATION_270: {
+ float xTemp = x;
+ x = mLocked.surfaceHeight - y;
+ y = xTemp;
+ orientation += M_PI_2;
+ if (orientation > M_PI_2) {
+ orientation -= M_PI;
+ }
+ break;
+ }
+ }
+
+ pointerIds[pointerCount] = int32_t(id);
+
+ pointerCoords[pointerCount].x = x;
+ pointerCoords[pointerCount].y = y;
+ pointerCoords[pointerCount].pressure = pressure;
+ pointerCoords[pointerCount].size = size;
+ pointerCoords[pointerCount].touchMajor = touchMajor;
+ pointerCoords[pointerCount].touchMinor = touchMinor;
+ pointerCoords[pointerCount].toolMajor = toolMajor;
+ pointerCoords[pointerCount].toolMinor = toolMinor;
+ pointerCoords[pointerCount].orientation = orientation;
+
+ if (id == changedId) {
+ motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ }
+
+ pointerCount += 1;
}
- if (pointerCoords[0].y <= 0) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
- } else if (pointerCoords[0].y >= mOrientedSurfaceHeight) {
- motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+
+ // Check edge flags by looking only at the first pointer since the flags are
+ // global to the event.
+ if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
+ if (pointerCoords[0].x <= 0) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
+ } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+ }
+ if (pointerCoords[0].y <= 0) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
+ } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
+ motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+ }
}
- }
+
+ xPrecision = mLocked.orientedXPrecision;
+ yPrecision = mLocked.orientedYPrecision;
+ } // release lock
getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags,
motionEventAction, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
pointerCount, pointerIds, pointerCoords,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ xPrecision, yPrecision, mDownTime);
}
-bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
if (mAxes.x.valid && mAxes.y.valid) {
return x >= mAxes.x.minValue && x <= mAxes.x.maxValue
&& y >= mAxes.y.minValue && y <= mAxes.y.maxValue;
@@ -1674,9 +1744,11 @@
return true;
}
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLvk(int32_t x, int32_t y) {
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+ int32_t x, int32_t y) {
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
@@ -2224,50 +2296,53 @@
}
int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
+ if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
return AKEY_STATE_VIRTUAL;
}
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
if (virtualKey.keyCode == keyCode) {
return AKEY_STATE_UP;
}
}
- } // release virtual key lock
+ } // release lock
return AKEY_STATE_UNKNOWN;
}
int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
+ if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
return AKEY_STATE_VIRTUAL;
}
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
if (virtualKey.scanCode == scanCode) {
return AKEY_STATE_UP;
}
}
- } // release virtual key lock
+ } // release lock
return AKEY_STATE_UNKNOWN;
}
bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire virtual key lock
- AutoMutex _l(mVirtualKeyLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
+ size_t numVirtualKeys = mLocked.virtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mLocked.virtualKeys[i];
for (size_t i = 0; i < numCodes; i++) {
if (virtualKey.keyCode == keyCodes[i]) {
@@ -2275,7 +2350,7 @@
}
}
}
- } // release virtual key lock
+ } // release lock
return true;
}
@@ -2304,7 +2379,6 @@
void SingleTouchInputMapper::reset() {
TouchInputMapper::reset();
- // Reinitialize.
initialize();
}
@@ -2436,7 +2510,6 @@
void MultiTouchInputMapper::reset() {
TouchInputMapper::reset();
- // Reinitialize.
initialize();
}
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 9fe207c..4eb63e8 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -1,6 +1,6 @@
/*
**
- ** Copyright 2008, HTC Inc.
+ ** Copyright 2008, 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.
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index fef3e6e..73862c3 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -1,5 +1,5 @@
/*
- ** Copyright 2008, HTC Inc.
+ ** Copyright 2008, 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.
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index d12e558..1d1913d 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -1,6 +1,6 @@
/*
**
- ** Copyright 2008, HTC Inc.
+ ** Copyright 2008, 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.
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index f26676d..c40d285 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -344,7 +344,7 @@
status_t StagefrightRecorder::setParamMaxFileDurationUs(int64_t timeUs) {
LOGV("setParamMaxFileDurationUs: %lld us", timeUs);
- if (timeUs <= 1000000LL) { // XXX: 1 second
+ if (timeUs <= 100000LL) { // XXX: 100 milli-seconds
LOGE("Max file duration is too short: %lld us", timeUs);
return BAD_VALUE;
}
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index baf9f4f..9f712c3 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1615,6 +1615,16 @@
mOwner->write(kData2, sizeof(kData2));
mOwner->endBox(); // esds
+ } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
+ !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
+ // 3gpp2 Spec AMRSampleEntry fields
+ mOwner->beginBox("damr");
+ mOwner->writeCString(" "); // vendor: 4 bytes
+ mOwner->writeInt8(0); // decoder version
+ mOwner->writeInt16(0x83FF); // mode set: all enabled
+ mOwner->writeInt8(0); // mode change period
+ mOwner->writeInt8(1); // frames per sample
+ mOwner->endBox();
}
mOwner->endBox();
} else {
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c786f94..3b3904a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1,7 +1,6 @@
/*
**
** Copyright (C) 2008, The Android Open Source Project
-** Copyright (C) 2008 HTC Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index b0b2d7a..77ccf41 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -1,7 +1,6 @@
/*
**
** Copyright (C) 2008, The Android Open Source Project
-** Copyright (C) 2008 HTC Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index bcbda3e..162fffe 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6101,17 +6101,19 @@
}
public void handleApplicationStrictModeViolation(
- IBinder app, int violationMask, ApplicationErrorReport.CrashInfo crashInfo) {
+ IBinder app,
+ int violationMask,
+ StrictMode.ViolationInfo info) {
ProcessRecord r = findAppProcess(app);
if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
- Integer stackFingerprint = crashInfo.stackTrace.hashCode();
+ Integer stackFingerprint = info.crashInfo.stackTrace.hashCode();
boolean logIt = true;
synchronized (mAlreadyLoggedViolatedStacks) {
if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
logIt = false;
// TODO: sub-sample into EventLog for these, with
- // the crashInfo.durationMillis? Then we'd get
+ // the info.durationMillis? Then we'd get
// the relative pain numbers, without logging all
// the stack traces repeatedly. We'd want to do
// likewise in the client code, which also does
@@ -6124,7 +6126,7 @@
}
}
if (logIt) {
- logStrictModeViolationToDropBox(r, crashInfo);
+ logStrictModeViolationToDropBox(r, info);
}
}
@@ -6139,7 +6141,7 @@
data.put("result", result);
data.put("app", r);
data.put("violationMask", violationMask);
- data.put("crashInfo", crashInfo);
+ data.put("info", info);
msg.obj = data;
mHandler.sendMessage(msg);
@@ -6154,9 +6156,10 @@
// these in quick succession so we try to batch these together to
// minimize disk writes, number of dropbox entries, and maximize
// compression, by having more fewer, larger records.
- private void logStrictModeViolationToDropBox(ProcessRecord process,
- ApplicationErrorReport.CrashInfo crashInfo) {
- if (crashInfo == null) {
+ private void logStrictModeViolationToDropBox(
+ ProcessRecord process,
+ StrictMode.ViolationInfo info) {
+ if (info == null) {
return;
}
final boolean isSystemApp = process == null ||
@@ -6177,12 +6180,16 @@
appendDropBoxProcessHeaders(process, sb);
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
sb.append("System-App: ").append(isSystemApp).append("\n");
- if (crashInfo != null && crashInfo.durationMillis != -1) {
- sb.append("Duration-Millis: ").append(crashInfo.durationMillis).append("\n");
+ sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
+ if (info.violationNumThisLoop != 0) {
+ sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
+ }
+ if (info != null && info.durationMillis != -1) {
+ sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
}
sb.append("\n");
- if (crashInfo != null && crashInfo.stackTrace != null) {
- sb.append(crashInfo.stackTrace);
+ if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
+ sb.append(info.crashInfo.stackTrace);
}
sb.append("\n");