Merge "Read iface stats from single proc file."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index eb8471a..1c85279 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -114,6 +114,7 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/Lohit_Hindi.ttf)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 034e3c7..4a144a2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3246,6 +3246,7 @@
try {
String resolvedType = null;
if (fillInIntent != null) {
+ fillInIntent.setAllowFds(false);
resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
}
int result = ActivityManagerNative.getDefault()
@@ -3370,6 +3371,7 @@
if (mParent == null) {
int result = IActivityManager.START_RETURN_INTENT_TO_CALLER;
try {
+ intent.setAllowFds(false);
result = ActivityManagerNative.getDefault()
.startActivity(mMainThread.getApplicationThread(),
intent, intent.resolveTypeIfNeeded(
@@ -3419,6 +3421,7 @@
public boolean startNextMatchingActivity(Intent intent) {
if (mParent == null) {
try {
+ intent.setAllowFds(false);
return ActivityManagerNative.getDefault()
.startNextMatchingActivity(mToken, intent);
} catch (RemoteException e) {
@@ -3692,6 +3695,9 @@
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
+ if (resultData != null) {
+ resultData.setAllowFds(false);
+ }
if (ActivityManagerNative.getDefault()
.finishActivity(mToken, resultCode, resultData)) {
mFinished = true;
@@ -3812,6 +3818,7 @@
int flags) {
String packageName = getPackageName();
try {
+ data.setAllowFds(false);
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_ACTIVITY_RESULT, packageName,
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0776e10..99aae37 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2674,6 +2674,7 @@
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
state = new Bundle();
+ state.setAllowFds(false);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
r.state = state;
}
@@ -2775,6 +2776,7 @@
if (!r.activity.mFinished && saveState) {
if (r.state == null) {
state = new Bundle();
+ state.setAllowFds(false);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
r.state = state;
} else {
@@ -3306,6 +3308,7 @@
}
if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
r.state = new Bundle();
+ r.state.setAllowFds(false);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 2139704..2bf1fb7 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -874,6 +874,7 @@
try {
String resolvedType = null;
if (fillInIntent != null) {
+ fillInIntent.setAllowFds(false);
resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
}
int result = ActivityManagerNative.getDefault()
@@ -892,6 +893,7 @@
public void sendBroadcast(Intent intent) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
+ intent.setAllowFds(false);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, false, false);
@@ -903,6 +905,7 @@
public void sendBroadcast(Intent intent, String receiverPermission) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
+ intent.setAllowFds(false);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermission, false, false);
@@ -915,6 +918,7 @@
String receiverPermission) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
+ intent.setAllowFds(false);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermission, true, false);
@@ -946,6 +950,7 @@
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
+ intent.setAllowFds(false);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, receiverPermission,
@@ -958,6 +963,7 @@
public void sendStickyBroadcast(Intent intent) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
+ intent.setAllowFds(false);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, false, true);
@@ -989,6 +995,7 @@
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
+ intent.setAllowFds(false);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, rd,
initialCode, initialData, initialExtras, null,
@@ -1005,6 +1012,7 @@
intent.setDataAndType(intent.getData(), resolvedType);
}
try {
+ intent.setAllowFds(false);
ActivityManagerNative.getDefault().unbroadcastIntent(
mMainThread.getApplicationThread(), intent);
} catch (RemoteException e) {
@@ -1069,6 +1077,7 @@
@Override
public ComponentName startService(Intent service) {
try {
+ service.setAllowFds(false);
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()));
@@ -1086,6 +1095,7 @@
@Override
public boolean stopService(Intent service) {
try {
+ service.setAllowFds(false);
int res = ActivityManagerNative.getDefault().stopService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()));
@@ -1116,6 +1126,7 @@
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
flags |= BIND_WAIVE_PRIORITY;
}
+ service.setAllowFds(false);
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
@@ -1148,6 +1159,9 @@
public boolean startInstrumentation(ComponentName className,
String profileFile, Bundle arguments) {
try {
+ if (arguments != null) {
+ arguments.setAllowFds(false);
+ }
return ActivityManagerNative.getDefault().startInstrumentation(
className, profileFile, 0, arguments, null);
} catch (RemoteException e) {
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index f3bc495..d7f5c55 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1375,6 +1375,7 @@
}
}
try {
+ intent.setAllowFds(false);
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
@@ -1415,6 +1416,7 @@
try {
String[] resolvedTypes = new String[intents.length];
for (int i=0; i<intents.length; i++) {
+ intents[i].setAllowFds(false);
resolvedTypes[i] = intents[i].resolveTypeIfNeeded(who.getContentResolver());
}
int result = ActivityManagerNative.getDefault()
@@ -1471,6 +1473,7 @@
}
}
try {
+ intent.setAllowFds(false);
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 2549c84..522f477 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -661,6 +661,9 @@
"Finishing broadcast to unregistered receiver");
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
+ if (extras != null) {
+ extras.setAllowFds(false);
+ }
mgr.finishReceiver(this, resultCode, data, extras, false);
} catch (RemoteException e) {
Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index b4827cb..b0637a7 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -192,6 +192,7 @@
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
+ intent.setAllowFds(false);
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_ACTIVITY, packageName,
@@ -249,6 +250,7 @@
String packageName = context.getPackageName();
String[] resolvedTypes = new String[intents.length];
for (int i=0; i<intents.length; i++) {
+ intents[i].setAllowFds(false);
resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());
}
try {
@@ -287,6 +289,7 @@
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
+ intent.setAllowFds(false);
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_BROADCAST, packageName,
@@ -324,6 +327,7 @@
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
+ intent.setAllowFds(false);
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_SERVICE, packageName,
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index 028149b..3cbaf92 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -366,6 +366,9 @@
mFinished = true;
try {
+ if (mResultExtras != null) {
+ mResultExtras.setAllowFds(false);
+ }
if (mOrderedHint) {
am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
mAbortBroadcast);
@@ -462,6 +465,7 @@
IActivityManager am = ActivityManagerNative.getDefault();
IBinder binder = null;
try {
+ service.setAllowFds(false);
binder = am.peekService(service, service.resolveTypeIfNeeded(
myContext.getContentResolver()));
} catch (RemoteException e) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index f44d038..08fe0aa 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3568,6 +3568,13 @@
return mExtras != null && mExtras.hasFileDescriptors();
}
+ /** @hide */
+ public void setAllowFds(boolean allowFds) {
+ if (mExtras != null) {
+ mExtras.setAllowFds(allowFds);
+ }
+ }
+
/**
* Retrieve extended data from the intent.
*
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 127efa2..4225393 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -1301,7 +1301,7 @@
elapsedTime = authoritySyncStats.elapsedTime;
times = authoritySyncStats.times;
- timeStr = String.format("%d/%d%%",
+ timeStr = String.format("%ds/%d%%",
elapsedTime / 1000,
elapsedTime * 100 / totalElapsedTime);
timesStr = String.format("%d/%d%%",
@@ -1309,32 +1309,30 @@
times * 100 / totalTimes);
pw.printf(authorityFormat, name, timesStr, timeStr);
- if (authoritySyncStats.accountMap.size() > 1) {
- final List<AccountSyncStats> sortedAccounts =
- new ArrayList<AccountSyncStats>(
- authoritySyncStats.accountMap.values());
- Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() {
- @Override
- public int compare(AccountSyncStats lhs, AccountSyncStats rhs) {
- // reverse order
- int compare = Integer.compare(rhs.times, lhs.times);
- if (compare == 0) {
- compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
- }
- return compare;
+ final List<AccountSyncStats> sortedAccounts =
+ new ArrayList<AccountSyncStats>(
+ authoritySyncStats.accountMap.values());
+ Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() {
+ @Override
+ public int compare(AccountSyncStats lhs, AccountSyncStats rhs) {
+ // reverse order
+ int compare = Integer.compare(rhs.times, lhs.times);
+ if (compare == 0) {
+ compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime);
}
- });
- for (AccountSyncStats stats: sortedAccounts) {
- elapsedTime = stats.elapsedTime;
- times = stats.times;
- timeStr = String.format("%d/%d%%",
- elapsedTime / 1000,
- elapsedTime * 100 / totalElapsedTime);
- timesStr = String.format("%d/%d%%",
- times,
- times * 100 / totalTimes);
- pw.printf(accountFormat, stats.name, timesStr, timeStr);
+ return compare;
}
+ });
+ for (AccountSyncStats stats: sortedAccounts) {
+ elapsedTime = stats.elapsedTime;
+ times = stats.times;
+ timeStr = String.format("%ds/%d%%",
+ elapsedTime / 1000,
+ elapsedTime * 100 / totalElapsedTime);
+ timesStr = String.format("%d/%d%%",
+ times,
+ times * 100 / totalTimes);
+ pw.printf(accountFormat, stats.name, timesStr, timeStr);
}
pw.println(separator);
}
@@ -1342,9 +1340,8 @@
pw.println();
pw.println("Recent Sync History");
final String format = " %-" + maxAccount + "s %s\n";
- String lastAuthorityName = null;
- String lastAccountKey = null;
- long lastEventTime = 0;
+ final Map<String, Long> lastTimeMap = Maps.newHashMap();
+
for (int i = 0; i < N; i++) {
SyncStorageEngine.SyncHistoryItem item = items.get(i);
SyncStorageEngine.AuthorityInfo authority
@@ -1363,21 +1360,32 @@
final long eventTime = item.eventTime;
time.set(eventTime);
- pw.printf(" #%-3d: %s %8s %5.1fs",
+ final String key = authorityName + "/" + accountKey;
+ final Long lastEventTime = lastTimeMap.get(key);
+ final String diffString;
+ if (lastEventTime == null) {
+ diffString = "";
+ } else {
+ final long diff = (lastEventTime - eventTime) / 1000;
+ if (diff < 60) {
+ diffString = String.valueOf(diff);
+ } else if (diff < 3600) {
+ diffString = String.format("%02d:%02d", diff / 60, diff % 60);
+ } else {
+ final long sec = diff % 3600;
+ diffString = String.format("%02d:%02d:%02d",
+ diff / 3600, sec / 60, sec % 60);
+ }
+ }
+ lastTimeMap.put(key, eventTime);
+
+ pw.printf(" #%-3d: %s %8s %5.1fs %8s",
i + 1,
formatTime(eventTime),
SyncStorageEngine.SOURCES[item.source],
- ((float) elapsedTime) / 1000);
- if (authorityName.equals(lastAuthorityName) && accountKey.equals(lastAccountKey)) {
- final long span = (lastEventTime - eventTime) / 1000;
- pw.printf(" %02d:%02d\n", span / 60, span % 60);
- } else {
- pw.printf(format, accountKey, authorityName);
- }
-
- lastAuthorityName = authorityName;
- lastAccountKey = accountKey;
- lastEventTime = eventTime;
+ ((float) elapsedTime) / 1000,
+ diffString);
+ pw.printf(format, accountKey, authorityName);
if (item.event != SyncStorageEngine.EVENT_STOP
|| item.upstreamActivity != 0
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 79c9395..fc6a44a 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -336,17 +336,17 @@
DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
if (dhcpAction == DhcpAction.START) {
- Log.d(TAG, "DHCP request on " + mInterfaceName);
+ if (DBG) Log.d(TAG, "DHCP request on " + mInterfaceName);
success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
mDhcpInfo = dhcpInfoInternal;
} else if (dhcpAction == DhcpAction.RENEW) {
- Log.d(TAG, "DHCP renewal on " + mInterfaceName);
+ if (DBG) Log.d(TAG, "DHCP renewal on " + mInterfaceName);
success = NetworkUtils.runDhcpRenew(mInterfaceName, dhcpInfoInternal);
dhcpInfoInternal.updateFromDhcpRequest(mDhcpInfo);
}
if (success) {
- Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
+ if (DBG) Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
long leaseDuration = dhcpInfoInternal.leaseDuration; //int to long conversion
//Sanity check for renewal
@@ -366,7 +366,7 @@
mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpInfoInternal)
.sendToTarget();
} else {
- Log.d(TAG, "DHCP failed on " + mInterfaceName + ": " +
+ Log.e(TAG, "DHCP failed on " + mInterfaceName + ": " +
NetworkUtils.getDhcpError());
NetworkUtils.stopDhcp(mInterfaceName);
mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0)
diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java
index 3291e6b..11acabe 100644
--- a/core/java/android/net/DnsPinger.java
+++ b/core/java/android/net/DnsPinger.java
@@ -22,7 +22,7 @@
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
-import android.util.Slog;
+import android.util.Log;
import com.android.internal.util.Protocol;
@@ -51,7 +51,7 @@
* @hide
*/
public final class DnsPinger extends Handler {
- private static final boolean V = true;
+ private static final boolean DBG = false;
private static final int RECEIVE_POLL_INTERVAL_MS = 200;
private static final int DNS_PORT = 53;
@@ -154,7 +154,7 @@
newActivePing.socket.setNetworkInterface(NetworkInterface.getByName(
getCurrentLinkProperties().getInterfaceName()));
} catch (Exception e) {
- Slog.w(TAG,"sendDnsPing::Error binding to socket", e);
+ loge("sendDnsPing::Error binding to socket " + e);
}
newActivePing.packetId = (short) sRandom.nextInt();
@@ -165,8 +165,8 @@
// Send the DNS query
DatagramPacket packet = new DatagramPacket(buf,
buf.length, dnsAddress, DNS_PORT);
- if (V) {
- Slog.v(TAG, "Sending a ping " + newActivePing.internalId +
+ if (DBG) {
+ log("Sending a ping " + newActivePing.internalId +
" to " + dnsAddress.getHostAddress()
+ " with packetId " + newActivePing.packetId + ".");
}
@@ -196,15 +196,15 @@
curPing.result =
(int) (SystemClock.elapsedRealtime() - curPing.start);
} else {
- if (V) {
- Slog.v(TAG, "response ID didn't match, ignoring packet");
+ if (DBG) {
+ log("response ID didn't match, ignoring packet");
}
}
} catch (SocketTimeoutException e) {
// A timeout here doesn't mean anything - squelsh this exception
} catch (Exception e) {
- if (V) {
- Slog.v(TAG, "DnsPinger.pingDns got socket exception: ", e);
+ if (DBG) {
+ log("DnsPinger.pingDns got socket exception: " + e);
}
curPing.result = SOCKET_EXCEPTION;
}
@@ -244,13 +244,13 @@
public List<InetAddress> getDnsList() {
LinkProperties curLinkProps = getCurrentLinkProperties();
if (curLinkProps == null) {
- Slog.e(TAG, "getCurLinkProperties:: LP for type" + mConnectionType + " is null!");
+ loge("getCurLinkProperties:: LP for type" + mConnectionType + " is null!");
return mDefaultDns;
}
Collection<InetAddress> dnses = curLinkProps.getDnses();
if (dnses == null || dnses.size() == 0) {
- Slog.v(TAG, "getDns::LinkProps has null dns - returning default");
+ loge("getDns::LinkProps has null dns - returning default");
return mDefaultDns;
}
@@ -277,8 +277,8 @@
}
private void sendResponse(int internalId, int externalId, int responseVal) {
- if(V) {
- Slog.d(TAG, "Responding to packet " + internalId +
+ if(DBG) {
+ log("Responding to packet " + internalId +
" externalId " + externalId +
" and val " + responseVal);
}
@@ -304,7 +304,7 @@
try {
return NetworkUtils.numericToInetAddress(dns);
} catch (IllegalArgumentException e) {
- Slog.w(TAG, "getDefaultDns::malformed default dns address");
+ loge("getDefaultDns::malformed default dns address");
return null;
}
}
@@ -323,4 +323,12 @@
0, 1, // QTYPE, set to 1 = A (host address)
0, 1 // QCLASS, set to 1 = IN (internet)
};
+
+ private void log(String s) {
+ Log.d(TAG, s);
+ }
+
+ private void loge(String s) {
+ Log.e(TAG, s);
+ }
}
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index c288f8a..28206b7 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -54,6 +54,7 @@
private boolean mHasFds = false;
private boolean mFdsKnown = true;
+ private boolean mAllowFds = true;
/**
* The ClassLoader used when unparcelling data from mParcelledData.
@@ -186,7 +187,14 @@
public ClassLoader getClassLoader() {
return mClassLoader;
}
-
+
+ /** @hide */
+ public boolean setAllowFds(boolean allowFds) {
+ boolean orig = mAllowFds;
+ mAllowFds = allowFds;
+ return orig;
+ }
+
/**
* Clones the current Bundle. The internal map is cloned, but the keys and
* values to which it refers are copied by reference.
@@ -1589,24 +1597,29 @@
* @param parcel The parcel to copy this bundle to.
*/
public void writeToParcel(Parcel parcel, int flags) {
- if (mParcelledData != null) {
- int length = mParcelledData.dataSize();
- parcel.writeInt(length);
- parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
- parcel.appendFrom(mParcelledData, 0, length);
- } else {
- parcel.writeInt(-1); // dummy, will hold length
- parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
-
- int oldPos = parcel.dataPosition();
- parcel.writeMapInternal(mMap);
- int newPos = parcel.dataPosition();
-
- // Backpatch length
- parcel.setDataPosition(oldPos - 8);
- int length = newPos - oldPos;
- parcel.writeInt(length);
- parcel.setDataPosition(newPos);
+ final boolean oldAllowFds = parcel.pushAllowFds(mAllowFds);
+ try {
+ if (mParcelledData != null) {
+ int length = mParcelledData.dataSize();
+ parcel.writeInt(length);
+ parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+ parcel.appendFrom(mParcelledData, 0, length);
+ } else {
+ parcel.writeInt(-1); // dummy, will hold length
+ parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+
+ int oldPos = parcel.dataPosition();
+ parcel.writeMapInternal(mMap);
+ int newPos = parcel.dataPosition();
+
+ // Backpatch length
+ parcel.setDataPosition(oldPos - 8);
+ int length = newPos - oldPos;
+ parcel.writeInt(length);
+ parcel.setDataPosition(newPos);
+ }
+ } finally {
+ parcel.restoreAllowFds(oldAllowFds);
}
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index e9ed676..15e3af4 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -323,6 +323,12 @@
*/
public final native void setDataCapacity(int size);
+ /** @hide */
+ public final native boolean pushAllowFds(boolean allowFds);
+
+ /** @hide */
+ public final native void restoreAllowFds(boolean lastValue);
+
/**
* Returns the raw bytes of the parcel.
*
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 886edaf..6d14dfc 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -238,6 +238,14 @@
public static final String CACHED_PHOTO_ID = "photo_id";
/**
+ * The cached formatted phone number.
+ * This value is not guaranteed to be present.
+ * <P>Type: TEXT</P>
+ * @hide
+ */
+ public static final String CACHED_FORMATTED_NUMBER = "formatted_number";
+
+ /**
* Adds a call to the call log.
*
* @param ci the CallerInfo object to get the target contact from. Can be null
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
index d26364e..da7c489 100644
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ b/core/java/android/server/BluetoothAdapterStateMachine.java
@@ -77,6 +77,12 @@
static final int PER_PROCESS_TURN_ON = 3;
static final int PER_PROCESS_TURN_OFF = 4;
+ // Turn on Bluetooth Module, Load firmware, and do all the preparation
+ // needed to get the Bluetooth Module ready but keep it not discoverable
+ // and not connectable. This way the Bluetooth Module can be quickly
+ // switched on if needed
+ static final int TURN_HOT = 5;
+
// Message(what) to report a event that the state machine need to respond to
//
// Event indicates sevice records have been loaded
@@ -94,23 +100,18 @@
// private internal messages
//
- // Turn on Bluetooth Module, Load firmware, and do all the preparation
- // needed to get the Bluetooth Module ready but keep it not discoverable
- // and not connectable. This way the Bluetooth Module can be quickly
- // switched on if needed
- private static final int TURN_HOT = 101;
// USER_TURN_ON is changed to TURN_ON_CONTINUE after we broadcast the
// state change intent so that we will not broadcast the intent again in
// other state
- private static final int TURN_ON_CONTINUE = 102;
+ private static final int TURN_ON_CONTINUE = 101;
// Unload firmware, turning off Bluetooth module power
- private static final int TURN_COLD = 103;
+ private static final int TURN_COLD = 102;
// Device disconnecting timeout happens
- private static final int DEVICES_DISCONNECT_TIMEOUT = 104;
+ private static final int DEVICES_DISCONNECT_TIMEOUT = 103;
// Prepare Bluetooth timeout happens
- private static final int PREPARE_BLUETOOTH_TIMEOUT = 105;
+ private static final int PREPARE_BLUETOOTH_TIMEOUT = 104;
// Bluetooth Powerdown timeout happens
- private static final int POWER_DOWN_TIMEOUT = 106;
+ private static final int POWER_DOWN_TIMEOUT = 105;
private Context mContext;
private BluetoothService mBluetoothService;
@@ -156,11 +157,6 @@
setInitialState(mPowerOff);
mPublicState = BluetoothAdapter.STATE_OFF;
-
- if (mContext.getResources().getBoolean
- (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
- sendMessage(TURN_HOT);
- }
}
/**
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 63da926..9ca5847 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -313,6 +313,10 @@
mAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothState = new BluetoothAdapterStateMachine(mContext, this, mAdapter);
mBluetoothState.start();
+ if (mContext.getResources().getBoolean
+ (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
+ mBluetoothState.sendMessage(BluetoothAdapterStateMachine.TURN_HOT);
+ }
mEventLoop = mBluetoothState.getBluetoothEventLoop();
}
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index e954983..34e7d4d 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -153,6 +153,18 @@
public abstract MenuInflater getMenuInflater();
/**
+ * Returns whether the UI presenting this action mode can take focus or not.
+ * This is used by internal components within the framework that would otherwise
+ * present an action mode UI that requires focus, such as an EditText as a custom view.
+ *
+ * @return true if the UI used to show this action mode can take focus
+ * @hide Internal use only
+ */
+ public boolean isUiFocusable() {
+ return true;
+ }
+
+ /**
* Callback interface for action modes. Supplied to
* {@link View#startActionMode(Callback)}, a Callback
* configures and handles events raised by a user's interaction with an action mode.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d193d6e..9628afb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1487,6 +1487,18 @@
}
/**
+ * Accessibility event types that are dispatched for text population.
+ */
+ private static final int POPULATING_ACCESSIBILITY_EVENT_TYPES =
+ AccessibilityEvent.TYPE_VIEW_CLICKED
+ | AccessibilityEvent.TYPE_VIEW_LONG_CLICKED
+ | AccessibilityEvent.TYPE_VIEW_SELECTED
+ | AccessibilityEvent.TYPE_VIEW_FOCUSED
+ | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
+ | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
+ | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT;
+
+ /**
* Temporary Rect currently for use in setBackground(). This will probably
* be extended in the future to hold our own class with more than just
* a Rect. :)
@@ -3855,7 +3867,10 @@
return;
}
onInitializeAccessibilityEvent(event);
- dispatchPopulateAccessibilityEvent(event);
+ // Only a subset of accessibility events populates text content.
+ if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
+ dispatchPopulateAccessibilityEvent(event);
+ }
// In the beginning we called #isShown(), so we know that getParent() is not null.
getParent().requestSendAccessibilityEvent(this, event);
}
@@ -3876,6 +3891,10 @@
* {@link AccessibilityDelegate#dispatchPopulateAccessibilityEvent(View, AccessibilityEvent)}
* is responsible for handling this call.
* </p>
+ * <p>
+ * <em>Note:</em> Accessibility events of certain types are not dispatched for
+ * populating the event text via this method. For details refer to {@link AccessibilityEvent}.
+ * </p>
*
* @param event The event.
*
@@ -3895,12 +3914,6 @@
* Note: Called from the default {@link AccessibilityDelegate}.
*/
boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
- // Do not populate text to scroll events. They describe position change
- // and usually come from container with a lot of text which is not very
- // informative for accessibility purposes. Also they are fired frequently.
- if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
- return true;
- }
onPopulateAccessibilityEvent(event);
return false;
}
@@ -12093,6 +12106,39 @@
}
/**
+ * Finds a view by its unuque and stable accessibility id.
+ *
+ * @param accessibilityId The searched accessibility id.
+ * @return The found view.
+ */
+ final View findViewByAccessibilityId(int accessibilityId) {
+ if (accessibilityId < 0) {
+ return null;
+ }
+ return findViewByAccessibilityIdTraversal(accessibilityId);
+ }
+
+ /**
+ * Performs the traversal to find a view by its unuque and stable accessibility id.
+ *
+ * <strong>Note:</strong>This method does not stop at the root namespace
+ * boundary since the user can touch the screen at an arbitrary location
+ * potentially crossing the root namespace bounday which will send an
+ * accessibility event to accessibility services and they should be able
+ * to obtain the event source. Also accessibility ids are guaranteed to be
+ * unique in the window.
+ *
+ * @param accessibilityId The accessibility id.
+ * @return The found view.
+ */
+ View findViewByAccessibilityIdTraversal(int accessibilityId) {
+ if (getAccessibilityViewId() == accessibilityId) {
+ return this;
+ }
+ return null;
+ }
+
+ /**
* Look for a child view with the given tag. If this view has the given
* tag, return this view.
*
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index fb0d80a..5b4a6f8 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -821,6 +821,24 @@
}
}
+ @Override
+ View findViewByAccessibilityIdTraversal(int accessibilityId) {
+ View foundView = super.findViewByAccessibilityIdTraversal(accessibilityId);
+ if (foundView != null) {
+ return foundView;
+ }
+ final int childrenCount = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i = 0; i < childrenCount; i++) {
+ View child = children[i];
+ foundView = child.findViewByAccessibilityIdTraversal(accessibilityId);
+ if (foundView != null) {
+ return foundView;
+ }
+ }
+ return null;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9cb4e5e..e7c91f9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -74,7 +74,6 @@
import android.widget.Scroller;
import com.android.internal.policy.PolicyManager;
-import com.android.internal.util.Predicate;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.IInputMethodCallback;
import com.android.internal.view.IInputMethodSession;
@@ -4462,9 +4461,6 @@
final class AccessibilityInteractionController {
private static final int POOL_SIZE = 5;
- private FindByAccessibilitytIdPredicate mFindByAccessibilityIdPredicate =
- new FindByAccessibilitytIdPredicate();
-
private ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
new ArrayList<AccessibilityNodeInfo>();
@@ -4551,11 +4547,8 @@
AccessibilityNodeInfo info = null;
try {
- FindByAccessibilitytIdPredicate predicate = mFindByAccessibilityIdPredicate;
- predicate.init(accessibilityId);
- View root = ViewRootImpl.this.mView;
- View target = root.findViewByPredicate(predicate);
- if (target != null && target.getVisibility() == View.VISIBLE) {
+ View target = findViewByAccessibilityId(accessibilityId);
+ if (target != null) {
info = target.createAccessibilityNodeInfo();
}
} finally {
@@ -4794,25 +4787,12 @@
if (root == null) {
return null;
}
- mFindByAccessibilityIdPredicate.init(accessibilityId);
- View foundView = root.findViewByPredicate(mFindByAccessibilityIdPredicate);
- if (foundView == null || foundView.getVisibility() != View.VISIBLE) {
+ View foundView = root.findViewByAccessibilityId(accessibilityId);
+ if (foundView != null && foundView.getVisibility() != View.VISIBLE) {
return null;
}
return foundView;
}
-
- private final class FindByAccessibilitytIdPredicate implements Predicate<View> {
- public int mSearchedId;
-
- public void init(int searchedId) {
- mSearchedId = searchedId;
- }
-
- public boolean apply(View view) {
- return (view.getAccessibilityViewId() == mSearchedId);
- }
- }
}
private class SendWindowContentChangedAccessibilityEvent implements Runnable {
@@ -4820,18 +4800,7 @@
public void run() {
if (mView != null) {
- // Check again for accessibility state since this is executed delayed.
- AccessibilityManager accessibilityManager =
- AccessibilityManager.getInstance(mView.mContext);
- if (accessibilityManager.isEnabled()) {
- // Send the event directly since we do not want to append the
- // source text because this is the text for the entire window
- // and we just want to notify that the content has changed.
- AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
- mView.onInitializeAccessibilityEvent(event);
- accessibilityManager.sendAccessibilityEvent(event);
- }
+ mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
mIsPending = false;
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index c93b564..91fbb0e 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -69,14 +69,16 @@
* <em>Type:</em>{@link #TYPE_VIEW_CLICKED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
- * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
* <li>{@link #isEnabled()} - Whether the source is enabled.</li>
* <li>{@link #isPassword()} - Whether the source is password.</li>
* <li>{@link #isChecked()} - Whether the source is checked.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
* </p>
* <p>
@@ -85,14 +87,16 @@
* <em>Type:</em>{@link #TYPE_VIEW_LONG_CLICKED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
- * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
* <li>{@link #isEnabled()} - Whether the source is enabled.</li>
* <li>{@link #isPassword()} - Whether the source is password.</li>
* <li>{@link #isChecked()} - Whether the source is checked.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
* </p>
* <p>
@@ -101,16 +105,18 @@
* <em>Type:</em> {@link #TYPE_VIEW_SELECTED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
- * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
* <li>{@link #isEnabled()} - Whether the source is enabled.</li>
* <li>{@link #isPassword()} - Whether the source is password.</li>
* <li>{@link #isChecked()} - Whether the source is checked.</li>
* <li>{@link #getItemCount()} - The number of selectable items of the source.</li>
* <li>{@link #getCurrentItemIndex()} - The currently selected item index.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
* </p>
* <p>
@@ -119,16 +125,18 @@
* <em>Type:</em> {@link #TYPE_VIEW_FOCUSED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
- * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
* <li>{@link #isEnabled()} - Whether the source is enabled.</li>
* <li>{@link #isPassword()} - Whether the source is password.</li>
* <li>{@link #isChecked()} - Whether the source is checked.</li>
* <li>{@link #getItemCount()} - The number of focusable items on the screen.</li>
* <li>{@link #getCurrentItemIndex()} - The currently focused item index.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
* </p>
* <p>
@@ -137,6 +145,7 @@
* <em>Type:</em> {@link #TYPE_VIEW_TEXT_CHANGED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
@@ -149,7 +158,17 @@
* <li>{@link #getAddedCount()} - The number of added characters.</li>
* <li>{@link #getRemovedCount()} - The number of removed characters.</li>
* <li>{@link #getBeforeText()} - The text of the source before the change.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
* </p>
* <p>
* <b>View text selection changed</b> - represents the event of changing the text
@@ -157,35 +176,47 @@
* <em>Type:</em> {@link #TYPE_VIEW_TEXT_SELECTION_CHANGED} </br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
* <li>{@link #getText()} - The text of the source.</li>
- * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
* <li>{@link #isPassword()} - Whether the source is password.</li>
* <li>{@link #getFromIndex()} - The selection start index.</li>
* <li>{@link #getToIndex()} - The selection end index.</li>
* <li>{@link #getItemCount()} - The length of the source text.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
* </p>
* <p>
* <b>View scrolled</b> - represents the event of scrolling a view. If
* the source is a descendant of {@link android.widget.AdapterView} the
* scroll is reported in terms of visible items - the first visible item,
* the last visible item, and the total items - because the the source
- * is unaware if its pixel size since its adapter is responsible for
+ * is unaware of its pixel size since its adapter is responsible for
* creating views. In all other cases the scroll is reported as the current
* scroll on the X and Y axis respectively plus the height of the source in
* pixels.</br>
* <em>Type:</em> {@link #TYPE_VIEW_SCROLLED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
- * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
* <li>{@link #isEnabled()} - Whether the source is enabled.</li>
* <li>{@link #getScrollX()} - The horizontal offset of the source
* (without descendants of AdapterView)).</li>
@@ -197,56 +228,165 @@
* (for descendants of AdapterView).</li>
* <li>{@link #getItemCount()} - The total items of the source (for descendants of AdapterView)
* or the height of the source in pixels (all other cases).</li>
+ * <li>{@link #getText()} - Text for providing more context.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
* </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
* </p>
* <p>
* <b>TRANSITION TYPES</b></br>
* </p>
+ * <p>
* <b>Window state changed</b> - represents the event of opening a
* {@link android.widget.PopupWindow}, {@link android.view.Menu},
* {@link android.app.Dialog}, etc.</br>
* <em>Type:</em> {@link #TYPE_WINDOW_STATE_CHANGED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
- * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
* </ul>
* </p>
* <p>
* <b>Window content changed</b> - represents the event of change in the
* content of a window. This change can be adding/removing view, changing
* a view size, etc.</br>
+ * </p>
* <p>
* <strong>Note:</strong> This event is fired only for the window source of the
- * last accessibility event different from {@link #TYPE_NOTIFICATION_STATE_CHANGED})
+ * last accessibility event different from {@link #TYPE_NOTIFICATION_STATE_CHANGED}
* and its purpose is to notify clients that the content of the user interaction
- * window has changed.
- * </p>
+ * window has changed.</br>
* <em>Type:</em> {@link #TYPE_WINDOW_CONTENT_CHANGED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getSource()} - The source info (for registered clients).</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
* </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
+ * </p>
* <p>
* <b>NOTIFICATION TYPES</b></br>
+ * </p>
* <p>
* <b>Notification state changed</b> - represents the event showing
- * {@link android.app.Notification}.
+ * {@link android.app.Notification}.</br>
* <em>Type:</em> {@link #TYPE_NOTIFICATION_STATE_CHANGED}</br>
* <em>Properties:</em></br>
* <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
* <li>{@link #getClassName()} - The class name of the source.</li>
* <li>{@link #getPackageName()} - The package name of the source.</li>
* <li>{@link #getEventTime()} - The event time.</li>
- * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
* <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}.</li>
+ * <li>{@link #getText()} - Text for providing more context.</li>
* </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
+ * </p>
+ * <p>
+ * <b>EXPLORATION TYPES</b></br>
+ * </p>
+ * <p>
+ * <b>View hover enter</b> - represents the event of beginning to hover
+ * over a {@link android.view.View}. The hover may be generated via
+ * exploring the screen by touch or via a pointing device.</br>
+ * <em>Type:</em> {@link #TYPE_VIEW_HOVER_ENTER}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li>
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
+ * </ul>
+ * </p>
+ * <b>View hover exit</b> - represents the event of stopping to hover
+ * over a {@link android.view.View}. The hover may be generated via
+ * exploring the screen by touch or via a pointing device.</br>
+ * <em>Type:</em> {@link #TYPE_VIEW_HOVER_EXIT}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li>
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source's sub-tree.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #getContentDescription()} - The content description of the source.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * <b>Touch exploration gesture start</b> - represents the event of starting a touch
+ * exploring gesture.</br>
+ * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
+ * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
+ * </p>
+ * <p>
+ * <b>Touch exploration gesture end</b> - represents the event of ending a touch
+ * exploring gesture.</br>
+ * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_END}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ * <li>{@link #getEventType()} - The type of the event.</li>
+ * </ul>
+ * <em>Note:</em> This event type is not dispatched to descendants though
+ * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event
+ * source {@link android.view.View} and the sub-tree rooted at it will not receive
+ * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent)
+ * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add
+ * text content to such events is by setting the
+ * {@link android.R.styleable#View_contentDescription contentDescription} of the source
+ * view.</br>
* </p>
* <p>
* <b>Security note</b>
@@ -254,6 +394,7 @@
* Since an event contains the text of its source privacy can be compromised by leaking
* sensitive information such as passwords. To address this issue any event fired in response
* to manipulation of a PASSWORD field does NOT CONTAIN the text of the password.
+ * </p>
*
* @see android.view.accessibility.AccessibilityManager
* @see android.accessibilityservice.AccessibilityService
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index a322fa3d..7398262 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -180,6 +180,14 @@
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ if (!mode.isUiFocusable()) {
+ // If the action mode we're running in is not focusable the user
+ // will not be able to type into the find on page field. This
+ // should only come up when we're running in a dialog which is
+ // already less than ideal; disable the option for now.
+ return false;
+ }
+
mode.setCustomView(mCustomView);
mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_find,
menu);
diff --git a/core/java/android/webkit/SelectActionModeCallback.java b/core/java/android/webkit/SelectActionModeCallback.java
index 104deb1..8c174aa 100644
--- a/core/java/android/webkit/SelectActionModeCallback.java
+++ b/core/java/android/webkit/SelectActionModeCallback.java
@@ -17,13 +17,12 @@
package android.webkit;
import android.app.SearchManager;
+import android.content.Context;
import android.content.Intent;
import android.provider.Browser;
-import android.webkit.WebView;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.View;
class SelectActionModeCallback implements ActionMode.Callback {
private WebView mWebView;
@@ -45,9 +44,25 @@
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_copy,
- menu);
- mode.setTitle(com.android.internal.R.string.textSelectionCABTitle);
+ mode.getMenuInflater().inflate(com.android.internal.R.menu.webview_copy, menu);
+
+ final Context context = mWebView.getContext();
+ boolean allowText = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
+ mode.setTitle(allowText ?
+ context.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
+
+ if (!mode.isUiFocusable()) {
+ // If the action mode UI we're running in isn't capable of taking window focus
+ // the user won't be able to type into the find on page UI. Disable this functionality.
+ // (Note that this should only happen in floating dialog windows.)
+ // This can be removed once we can handle multiple focusable windows at a time
+ // in a better way.
+ final MenuItem findOnPageItem = menu.findItem(com.android.internal.R.id.find);
+ if (findOnPageItem != null) {
+ findOnPageItem.setVisible(false);
+ }
+ }
mActionMode = mode;
return true;
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 851c706..eaed9fe 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4078,8 +4078,8 @@
boolean pressed = (mTouchMode == TOUCH_SHORTPRESS_START_MODE
|| mTouchMode == TOUCH_INIT_MODE
|| mTouchMode == TOUCH_SHORTPRESS_MODE);
- nativeRecordButtons(hasFocus() && hasWindowFocus(),
- (pressed && !USE_WEBKIT_RINGS)
+ recordButtons(canvas,
+ hasFocus() && hasWindowFocus(), (pressed && !USE_WEBKIT_RINGS)
|| mTrackballDown || mGotCenterDown, false);
drawCoreAndCursorRing(canvas, mBackgroundColor,
mDrawCursorRing && drawRings);
@@ -5133,7 +5133,7 @@
.obtainMessage(LONG_PRESS_CENTER), LONG_PRESS_TIMEOUT);
// Already checked mNativeClass, so we do not need to check it
// again.
- nativeRecordButtons(hasFocus() && hasWindowFocus(), true, true);
+ recordButtons(null, hasFocus() && hasWindowFocus(), true, true);
if (!wantsKeyEvents) return true;
}
// Bubble up the key event as WebView doesn't handle it
@@ -5561,7 +5561,7 @@
mDrawCursorRing = true;
setFocusControllerActive(true);
if (mNativeClass != 0) {
- nativeRecordButtons(true, false, true);
+ recordButtons(null, true, false, true);
}
} else {
if (!inEditingMode()) {
@@ -5570,7 +5570,7 @@
mDrawCursorRing = false;
setFocusControllerActive(false);
}
- // We do not call nativeRecordButtons here because we assume
+ // We do not call recordButtons here because we assume
// that when we lost focus, or window focus, it got called with
// false for the first parameter
}
@@ -5589,7 +5589,7 @@
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
mTouchMode = TOUCH_DONE_MODE;
if (mNativeClass != 0) {
- nativeRecordButtons(false, false, true);
+ recordButtons(null, false, false, true);
}
setFocusControllerActive(false);
}
@@ -5647,13 +5647,13 @@
if (hasWindowFocus()) {
mDrawCursorRing = true;
if (mNativeClass != 0) {
- nativeRecordButtons(true, false, true);
+ recordButtons(null, true, false, true);
}
setFocusControllerActive(true);
//} else {
// The WebView has gained focus while we do not have
// windowfocus. When our window lost focus, we should have
- // called nativeRecordButtons(false...)
+ // called recordButtons(false...)
}
} else {
// When we lost focus, unless focus went to the TextView (which is
@@ -5661,7 +5661,7 @@
if (!inEditingMode()) {
mDrawCursorRing = false;
if (mNativeClass != 0) {
- nativeRecordButtons(false, false, true);
+ recordButtons(null, false, false, true);
}
setFocusControllerActive(false);
}
@@ -6762,7 +6762,7 @@
if (mNativeClass == 0) {
return false;
}
- nativeRecordButtons(hasFocus() && hasWindowFocus(), true, true);
+ recordButtons(null, hasFocus() && hasWindowFocus(), true, true);
if (time - mLastCursorTime <= TRACKBALL_TIMEOUT
&& !mLastCursorBounds.equals(nativeGetCursorRingBounds())) {
nativeSelectBestAt(mLastCursorBounds);
@@ -9349,6 +9349,24 @@
return nativeTileProfilingGetFloat(frame, tile, key);
}
+ /**
+ * Helper method to deal with differences between hardware and software rendering
+ */
+ private void recordButtons(Canvas canvas, boolean focus, boolean pressed,
+ boolean inval) {
+ boolean isHardwareAccel = canvas != null
+ ? canvas.isHardwareAccelerated()
+ : isHardwareAccelerated();
+ if (isHardwareAccel) {
+ // We never want to change button state if we are hardware accelerated,
+ // but we DO want to invalidate as necessary so that the GL ring
+ // can be drawn
+ nativeRecordButtons(false, false, inval);
+ } else {
+ nativeRecordButtons(focus, pressed, inval);
+ }
+ }
+
private native int nativeCacheHitFramePointer();
private native boolean nativeCacheHitIsPlugin();
private native Rect nativeCacheHitNodeBounds();
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index a4b4e78..61c5dd4 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -881,20 +881,14 @@
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- final int eventType = event.getEventType();
- switch (eventType) {
- case AccessibilityEvent.TYPE_VIEW_SCROLLED:
- // Do not populate the text of scroll events.
- return true;
- case AccessibilityEvent.TYPE_VIEW_FOCUSED:
- // This is an exceptional case which occurs when a window gets the
- // focus and sends a focus event via its focused child to announce
- // current focus/selection. AdapterView fires selection but not focus
- // events so we change the event type here.
- if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
- event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
- }
- break;
+ if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
+ // This is an exceptional case which occurs when a window gets the
+ // focus and sends a focus event via its focused child to announce
+ // current focus/selection. AdapterView fires selection but not focus
+ // events so we change the event type here.
+ if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
+ event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ }
}
View selectedView = getSelectedView();
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index 84ebec3..63a0870 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -25,6 +25,7 @@
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
+import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.View;
@@ -228,6 +229,8 @@
mMinutes = minute + second / 60.0f;
mHour = hour + mMinutes / 60.0f;
mChanged = true;
+
+ updateContentDescription(mCalendar);
}
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -243,4 +246,11 @@
invalidate();
}
};
+
+ private void updateContentDescription(Time time) {
+ final int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_24HOUR;
+ String contentDescription = DateUtils.formatDateTime(mContext,
+ time.toMillis(false), flags);
+ setContentDescription(contentDescription);
+ }
}
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 3f5b571c..a0eba9a 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -371,16 +371,6 @@
}
}
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- // Do not append text content to scroll events they are fired frequently
- // and the client has already received another event type with the text.
- if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
- super.dispatchPopulateAccessibilityEvent(event);
- }
- return false;
- }
-
/**
* Tracks a motion scroll. In reality, this is used to do just about any
* movement to items (touch scroll, arrow-key scroll, set an item as selected).
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 1bbc501..324dfd7 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -725,16 +725,6 @@
event.setScrollable(true);
}
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- // Do not append text content to scroll events they are fired frequently
- // and the client has already received another event type with the text.
- if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
- super.dispatchPopulateAccessibilityEvent(event);
- }
- return false;
- }
-
private int getScrollRange() {
int scrollRange = 0;
if (getChildCount() > 0) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 61ea5c9..3ac4e80 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -730,16 +730,6 @@
event.setScrollable(true);
}
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- // Do not append text content to scroll events they are fired frequently
- // and the client has already received another event type with the text.
- if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
- super.dispatchPopulateAccessibilityEvent(event);
- }
- return false;
- }
-
private int getScrollRange() {
int scrollRange = 0;
if (getChildCount() > 0) {
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index ac9535a..ce17184 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -30,8 +30,6 @@
import com.android.internal.util.ArrayUtils;
-import java.util.Locale;
-
/**
* Helper class for TextView. Bridge between the TextView and the Dictionnary service.
@@ -174,8 +172,6 @@
final int sequenceNumber = suggestionsInfo.getSequence();
for (int j = 0; j < mLength; j++) {
- final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j];
-
if (sequenceNumber == mIds[j]) {
final int attributes = suggestionsInfo.getSuggestionsAttributes();
boolean isInDictionary =
@@ -183,32 +179,79 @@
boolean looksLikeTypo =
((attributes & SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO) > 0);
+ SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j];
if (!isInDictionary && looksLikeTypo) {
- String[] suggestions = getSuggestions(suggestionsInfo);
- SuggestionSpan suggestionSpan = new SuggestionSpan(
- mTextView.getContext(), suggestions,
- SuggestionSpan.FLAG_EASY_CORRECT |
- SuggestionSpan.FLAG_MISSPELLED);
- final int start = editable.getSpanStart(spellCheckSpan);
- final int end = editable.getSpanEnd(spellCheckSpan);
- editable.setSpan(suggestionSpan, start, end,
- Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- // TODO limit to the word rectangle region
- mTextView.invalidate();
+ createMisspelledSuggestionSpan(editable, suggestionsInfo, spellCheckSpan);
}
editable.removeSpan(spellCheckSpan);
+ break;
}
}
}
}
- private static String[] getSuggestions(SuggestionsInfo suggestionsInfo) {
- // A negative suggestion count is possible
- final int len = Math.max(0, suggestionsInfo.getSuggestionsCount());
- String[] suggestions = new String[len];
- for (int j = 0; j < len; j++) {
- suggestions[j] = suggestionsInfo.getSuggestionAt(j);
+ private void createMisspelledSuggestionSpan(Editable editable, SuggestionsInfo suggestionsInfo,
+ SpellCheckSpan spellCheckSpan) {
+ final int start = editable.getSpanStart(spellCheckSpan);
+ final int end = editable.getSpanEnd(spellCheckSpan);
+
+ // Other suggestion spans may exist on that region, with identical suggestions, filter
+ // them out to avoid duplicates. First, filter suggestion spans on that exact region.
+ SuggestionSpan[] suggestionSpans = editable.getSpans(start, end, SuggestionSpan.class);
+ final int length = suggestionSpans.length;
+ for (int i = 0; i < length; i++) {
+ final int spanStart = editable.getSpanStart(suggestionSpans[i]);
+ final int spanEnd = editable.getSpanEnd(suggestionSpans[i]);
+ if (spanStart != start || spanEnd != end) {
+ suggestionSpans[i] = null;
+ break;
+ }
}
- return suggestions;
+
+ final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
+ String[] suggestions;
+ if (suggestionsCount <= 0) {
+ // A negative suggestion count is possible
+ suggestions = ArrayUtils.emptyArray(String.class);
+ } else {
+ int numberOfSuggestions = 0;
+ suggestions = new String[suggestionsCount];
+
+ for (int i = 0; i < suggestionsCount; i++) {
+ final String spellSuggestion = suggestionsInfo.getSuggestionAt(i);
+ if (spellSuggestion == null) break;
+ boolean suggestionFound = false;
+
+ for (int j = 0; j < length && !suggestionFound; j++) {
+ if (suggestionSpans[j] == null) break;
+
+ String[] suggests = suggestionSpans[j].getSuggestions();
+ for (int k = 0; k < suggests.length; k++) {
+ if (spellSuggestion.equals(suggests[k])) {
+ // The suggestion is already provided by an other SuggestionSpan
+ suggestionFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!suggestionFound) {
+ suggestions[numberOfSuggestions++] = spellSuggestion;
+ }
+ }
+
+ if (numberOfSuggestions != suggestionsCount) {
+ String[] newSuggestions = new String[numberOfSuggestions];
+ System.arraycopy(suggestions, 0, newSuggestions, 0, numberOfSuggestions);
+ suggestions = newSuggestions;
+ }
+ }
+
+ SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
+ SuggestionSpan.FLAG_EASY_CORRECT | SuggestionSpan.FLAG_MISSPELLED);
+ editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ // TODO limit to the word rectangle region
+ mTextView.invalidate();
}
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5cd7902..17f0e05 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -353,6 +353,8 @@
// Set when this TextView gained focus with some text selected. Will start selection mode.
private boolean mCreatedWithASelection = false;
+ // Size of the window for the word iterator, should be greater than the longest word's length
+ private static final int WORD_ITERATOR_WINDOW_WIDTH = 50;
private WordIterator mWordIterator;
private SpellChecker mSpellChecker;
@@ -2937,11 +2939,19 @@
Spannable sp = new SpannableString(mText);
- for (ChangeWatcher cw :
- sp.getSpans(0, sp.length(), ChangeWatcher.class)) {
+ for (ChangeWatcher cw : sp.getSpans(0, sp.length(), ChangeWatcher.class)) {
sp.removeSpan(cw);
}
+ SuggestionSpan[] suggestionSpans = sp.getSpans(0, sp.length(), SuggestionSpan.class);
+ for (int i = 0; i < suggestionSpans.length; i++) {
+ int flags = suggestionSpans[i].getFlags();
+ if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0
+ && (flags & SuggestionSpan.FLAG_MISSPELLED) != 0) {
+ sp.removeSpan(suggestionSpans[i]);
+ }
+ }
+
sp.removeSpan(mSuggestionRangeSpan);
ss.text = sp;
@@ -4449,7 +4459,6 @@
if (mSpellChecker != null) {
mSpellChecker.closeSession();
- removeMisspelledSpans();
// Forces the creation of a new SpellChecker next time this window is created.
// Will handle the cases where the settings has been changed in the meantime.
mSpellChecker = null;
@@ -7771,7 +7780,7 @@
// Iterate over the newly added text and schedule new SpellCheckSpans
while (wordStart <= shiftedEnd) {
- if (wordEnd >= shiftedStart) {
+ if (wordEnd >= shiftedStart && wordEnd > wordStart) {
// A new word has been created across the interval boundaries. Remove previous spans
if (wordStart < shiftedStart && wordEnd > shiftedStart) {
removeSpansAt(start, spellCheckSpans, text);
@@ -8461,24 +8470,6 @@
}
}
- /**
- * Removes the suggestion spans for misspelled words.
- */
- private void removeMisspelledSpans() {
- if (mText instanceof Spannable) {
- Spannable spannable = (Spannable) mText;
- SuggestionSpan[] suggestionSpans = spannable.getSpans(0,
- spannable.length(), SuggestionSpan.class);
- for (int i = 0; i < suggestionSpans.length; i++) {
- int flags = suggestionSpans[i].getFlags();
- if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0
- && (flags & SuggestionSpan.FLAG_MISSPELLED) != 0) {
- spannable.removeSpan(suggestionSpans[i]);
- }
- }
- }
- }
-
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (mMovement != null && mText instanceof Spannable && mLayout != null) {
@@ -8934,10 +8925,10 @@
// If a URLSpan (web address, email, phone...) is found at that position, select it.
URLSpan[] urlSpans = ((Spanned) mText).getSpans(minOffset, maxOffset, URLSpan.class);
- if (urlSpans.length == 1) {
- URLSpan url = urlSpans[0];
- selectionStart = ((Spanned) mText).getSpanStart(url);
- selectionEnd = ((Spanned) mText).getSpanEnd(url);
+ if (urlSpans.length >= 1) {
+ URLSpan urlSpan = urlSpans[0];
+ selectionStart = ((Spanned) mText).getSpanStart(urlSpan);
+ selectionEnd = ((Spanned) mText).getSpanEnd(urlSpan);
} else {
final int shift = prepareWordIterator(minOffset, maxOffset);
@@ -8948,10 +8939,42 @@
selectionEnd = mWordIterator.getEnd(maxOffset - shift);
if (selectionEnd == BreakIterator.DONE) return false;
selectionEnd += shift;
+
+ if (selectionStart == selectionEnd) {
+ // Possible when the word iterator does not properly handle the text's language
+ long range = getCharRange(selectionStart);
+ selectionStart = extractRangeStartFromLong(range);
+ selectionEnd = extractRangeEndFromLong(range);
+ }
}
Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
- return true;
+ return selectionEnd > selectionStart;
+ }
+
+ private long getCharRange(int offset) {
+ final int textLength = mText.length();
+ if (offset + 1 < textLength) {
+ final char currentChar = mText.charAt(offset);
+ final char nextChar = mText.charAt(offset + 1);
+ if (Character.isSurrogatePair(currentChar, nextChar)) {
+ return packRangeInLong(offset, offset + 2);
+ }
+ }
+ if (offset < textLength) {
+ return packRangeInLong(offset, offset + 1);
+ }
+ if (offset - 2 >= 0) {
+ final char previousChar = mText.charAt(offset - 1);
+ final char previousPreviousChar = mText.charAt(offset - 2);
+ if (Character.isSurrogatePair(previousPreviousChar, previousChar)) {
+ return packRangeInLong(offset - 2, offset);
+ }
+ }
+ if (offset - 1 >= 0) {
+ return packRangeInLong(offset - 1, offset);
+ }
+ return packRangeInLong(offset, offset);
}
int prepareWordIterator(int start, int end) {
@@ -8959,9 +8982,8 @@
mWordIterator = new WordIterator();
}
- final int TEXT_WINDOW_WIDTH = 50; // Should be larger than the longest word's length
- final int windowStart = Math.max(0, start - TEXT_WINDOW_WIDTH);
- final int windowEnd = Math.min(mText.length(), end + TEXT_WINDOW_WIDTH);
+ final int windowStart = Math.max(0, start - WORD_ITERATOR_WINDOW_WIDTH);
+ final int windowEnd = Math.min(mText.length(), end + WORD_ITERATOR_WINDOW_WIDTH);
mWordIterator.setCharSequence(mText.subSequence(windowStart, windowEnd));
return windowStart;
@@ -9340,7 +9362,7 @@
// Start a new selection
if (!handled) {
- handled = startSelectionActionMode();
+ vibrate = handled = startSelectionActionMode();
}
if (vibrate) {
@@ -9930,7 +9952,7 @@
// Fallback on the default highlight color when the first span does not provide one
mSuggestionRangeSpan.setBackgroundColor(mHighlightColor);
} else {
- final float BACKGROUND_TRANSPARENCY = 0.3f;
+ final float BACKGROUND_TRANSPARENCY = 0.4f;
final int newAlpha = (int) (Color.alpha(underlineColor) * BACKGROUND_TRANSPARENCY);
mSuggestionRangeSpan.setBackgroundColor(
(underlineColor & 0x00FFFFFF) + (newAlpha << 24));
@@ -9956,8 +9978,8 @@
suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// Add the text before and after the span.
- suggestionInfo.text.insert(0, mText.subSequence(unionStart, spanStart).toString());
- suggestionInfo.text.append(mText.subSequence(spanEnd, unionEnd).toString());
+ suggestionInfo.text.insert(0, mText.toString().substring(unionStart, spanStart));
+ suggestionInfo.text.append(mText.toString().substring(spanEnd, unionEnd));
}
@Override
@@ -9989,14 +10011,16 @@
hide();
return;
}
- final String originalText = mText.subSequence(spanStart, spanEnd).toString();
+ final String originalText = mText.toString().substring(spanStart, spanEnd);
if (suggestionInfo.suggestionIndex == ADD_TO_DICTIONARY) {
Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
intent.putExtra("word", originalText);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
- suggestionInfo.removeMisspelledFlag();
+ // There is no way to know if the word was indeed added. Re-check.
+ editable.removeSpan(suggestionInfo.suggestionSpan);
+ updateSpellCheckSpans(spanStart, spanEnd);
} else {
// SuggestionSpans are removed by replace: save them before
SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
@@ -10024,8 +10048,10 @@
if (!TextUtils.isEmpty(
suggestionInfo.suggestionSpan.getNotificationTargetClassName())) {
InputMethodManager imm = InputMethodManager.peekInstance();
- imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
- suggestionInfo.suggestionIndex);
+ if (imm != null) {
+ imm.notifySuggestionPicked(suggestionInfo.suggestionSpan, originalText,
+ suggestionInfo.suggestionIndex);
+ }
}
// Swap text content between actual text and Suggestion span
@@ -10045,7 +10071,7 @@
}
}
- // Move cursor at the end of the replacement word
+ // Move cursor at the end of the replaced word
Selection.setSelection(editable, spanEnd + lengthDifference);
}
@@ -10174,8 +10200,7 @@
if (!hasSelection()) {
// There may already be a selection on device rotation
- boolean currentWordSelected = selectCurrentWord();
- if (!currentWordSelected) {
+ if (!selectCurrentWord()) {
// No word found under cursor or text selection not permitted.
return false;
}
@@ -10256,7 +10281,8 @@
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
+ TypedArray styledAttributes = mContext.obtainStyledAttributes(
+ com.android.internal.R.styleable.SelectionModeDrawables);
boolean allowText = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
@@ -10269,7 +10295,7 @@
if (!allowText) {
// Provide an icon, text will not be displayed on smaller screens.
selectAllIconId = styledAttributes.getResourceId(
- R.styleable.Theme_actionModeSelectAllDrawable, 0);
+ R.styleable.SelectionModeDrawables_actionModeSelectAllDrawable, 0);
}
menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
@@ -10281,7 +10307,7 @@
if (canCut()) {
menu.add(0, ID_CUT, 0, com.android.internal.R.string.cut).
setIcon(styledAttributes.getResourceId(
- R.styleable.Theme_actionModeCutDrawable, 0)).
+ R.styleable.SelectionModeDrawables_actionModeCutDrawable, 0)).
setAlphabeticShortcut('x').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
@@ -10290,7 +10316,7 @@
if (canCopy()) {
menu.add(0, ID_COPY, 0, com.android.internal.R.string.copy).
setIcon(styledAttributes.getResourceId(
- R.styleable.Theme_actionModeCopyDrawable, 0)).
+ R.styleable.SelectionModeDrawables_actionModeCopyDrawable, 0)).
setAlphabeticShortcut('c').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
@@ -10299,7 +10325,7 @@
if (canPaste()) {
menu.add(0, ID_PASTE, 0, com.android.internal.R.string.paste).
setIcon(styledAttributes.getResourceId(
- R.styleable.Theme_actionModePasteDrawable, 0)).
+ R.styleable.SelectionModeDrawables_actionModePasteDrawable, 0)).
setAlphabeticShortcut('v').
setShowAsAction(
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 7444d46..f52e773 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -237,9 +237,7 @@
}
// set the content descriptions
- if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- setContentDescriptions();
- }
+ setContentDescriptions();
}
@Override
diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java
index ecda47e..edf4443 100644
--- a/core/java/com/android/internal/view/StandaloneActionMode.java
+++ b/core/java/com/android/internal/view/StandaloneActionMode.java
@@ -36,17 +36,19 @@
private ActionMode.Callback mCallback;
private WeakReference<View> mCustomView;
private boolean mFinished;
+ private boolean mFocusable;
private MenuBuilder mMenu;
public StandaloneActionMode(Context context, ActionBarContextView view,
- ActionMode.Callback callback) {
+ ActionMode.Callback callback, boolean isFocusable) {
mContext = context;
mContextView = view;
mCallback = callback;
mMenu = new MenuBuilder(context).setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
mMenu.setCallback(this);
+ mFocusable = isFocusable;
}
@Override
@@ -139,4 +141,8 @@
invalidate();
mContextView.showOverflowMenu();
}
+
+ public boolean isUiFocusable() {
+ return mFocusable;
+ }
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 4a38775..2694aa2 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -24,11 +24,15 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
import android.os.FileObserver;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.storage.IMountService;
import android.provider.Settings;
import android.security.KeyStore;
@@ -55,6 +59,8 @@
*/
public class LockPatternUtils {
+ private static final String OPTION_ENABLE_FACELOCK = "enable_facelock";
+
private static final String TAG = "LockPatternUtils";
private static final String SYSTEM_DIRECTORY = "/system/";
@@ -110,6 +116,7 @@
public static final String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate";
private final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt";
private final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled";
+ private final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
= "lockscreen.biometric_weak_fallback";
@@ -339,12 +346,21 @@
*/
public int getActivePasswordQuality() {
int activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
- switch (getKeyguardStoredPasswordQuality()) {
+ // Note we don't want to use getKeyguardStoredPasswordQuality() because we want this to
+ // return biometric_weak if that is being used instead of the backup
+ int quality =
+ (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ switch (quality) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
if (isLockPatternEnabled()) {
activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
}
break;
+ case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
+ if (isBiometricWeakInstalled()) {
+ activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+ }
+ break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
if (isLockPasswordEnabled()) {
activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
@@ -366,6 +382,7 @@
}
break;
}
+
return activePasswordQuality;
}
@@ -434,7 +451,7 @@
* Calls back SetupFaceLock to delete the gallery file when the lock type is changed
*/
void deleteGallery() {
- if(isBiometricEnabled()) {
+ if(usingBiometricWeak()) {
Intent intent = new Intent().setClassName("com.android.facelock",
"com.android.facelock.SetupFaceLock");
intent.putExtra("deleteGallery", true);
@@ -677,6 +694,9 @@
return quality;
}
+ /**
+ * @return true if the lockscreen method is set to biometric weak
+ */
public boolean usingBiometricWeak() {
int quality =
(int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
@@ -810,7 +830,7 @@
|| backupMode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
return savedPasswordExists() && (passwordEnabled ||
- (isBiometricEnabled() && backupEnabled));
+ (usingBiometricWeak() && backupEnabled));
}
/**
@@ -824,16 +844,36 @@
return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED)
&& (getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
== DevicePolicyManager.PASSWORD_QUALITY_SOMETHING ||
- (isBiometricEnabled() && backupEnabled));
+ (usingBiometricWeak() && backupEnabled));
}
/**
- * @return Whether biometric weak lock is enabled.
+ * @return Whether biometric weak lock is installed and that the front facing camera exists
*/
- public boolean isBiometricEnabled() {
- // TODO: check if it's installed
- return getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
- == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+ public boolean isBiometricWeakInstalled() {
+ // Check that the system flag was set
+ if (!OPTION_ENABLE_FACELOCK.equals(getString(LOCKSCREEN_OPTIONS))) {
+ return false;
+ }
+
+ // Check that it's installed
+ PackageManager pm = mContext.getPackageManager();
+ try {
+ pm.getPackageInfo("com.android.facelock", PackageManager.GET_ACTIVITIES);
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+
+ // Check that the camera is enabled
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
+ return false;
+ }
+ if (getDevicePolicyManager().getCameraDisabled(null)) {
+ return false;
+ }
+
+
+ return true;
}
/**
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 18bd754..da055fc 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -392,10 +392,20 @@
SkSafeUnref(ctable);
size_t size = bitmap->getSize();
+
+ android::Parcel::ReadableBlob blob;
+ android::status_t status = p->readBlob(size, &blob);
+ if (status) {
+ doThrowRE(env, "Could not read bitmap from parcel blob.");
+ delete bitmap;
+ return NULL;
+ }
+
bitmap->lockPixels();
- memcpy(bitmap->getPixels(), p->readInplace(size), size);
+ memcpy(bitmap->getPixels(), blob.data(), size);
bitmap->unlockPixels();
+ blob.release();
return GraphicsJNI::createBitmap(env, bitmap, buffer, isMutable, NULL, density);
}
@@ -431,17 +441,24 @@
}
size_t size = bitmap->getSize();
+
+ android::Parcel::WritableBlob blob;
+ android::status_t status = p->writeBlob(size, &blob);
+ if (status) {
+ doThrowRE(env, "Could not write bitmap to parcel blob.");
+ return false;
+ }
+
bitmap->lockPixels();
- void* pDst = p->writeInplace(size);
-
const void* pSrc = bitmap->getPixels();
-
if (pSrc == NULL) {
- memset(pDst, 0, size);
+ memset(blob.data(), 0, size);
} else {
- memcpy(pDst, pSrc, size);
+ memcpy(blob.data(), pSrc, size);
}
bitmap->unlockPixels();
+
+ blob.release();
return true;
}
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 494a2b3..1718e74 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -697,6 +697,10 @@
LOGE("!!! FAILED BINDER TRANSACTION !!!");
//jniThrowException(env, "java/lang/OutOfMemoryError", "Binder transaction too large");
break;
+ case FDS_NOT_ALLOWED:
+ jniThrowException(env, "java/lang/RuntimeException",
+ "Not allowed to write file descriptors here");
+ break;
default:
LOGE("Unknown binder error code. 0x%x", err);
}
@@ -1275,7 +1279,7 @@
if (parcel != NULL) {
const status_t err = parcel->setDataSize(size);
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1294,11 +1298,29 @@
if (parcel != NULL) {
const status_t err = parcel->setDataCapacity(size);
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
+static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jobject clazz, jboolean allowFds)
+{
+ Parcel* parcel = parcelForJavaObject(env, clazz);
+ jboolean ret = JNI_TRUE;
+ if (parcel != NULL) {
+ ret = (jboolean)parcel->pushAllowFds(allowFds);
+ }
+ return ret;
+}
+
+static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jobject clazz, jboolean lastValue)
+{
+ Parcel* parcel = parcelForJavaObject(env, clazz);
+ if (parcel != NULL) {
+ parcel->restoreAllowFds((bool)lastValue);
+ }
+}
+
static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz,
jobject data, jint offset,
jint length)
@@ -1310,12 +1332,13 @@
const status_t err = parcel->writeInt32(length);
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
+ return;
}
void* dest = parcel->writeInplace(length);
if (dest == NULL) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, NO_MEMORY);
return;
}
@@ -1333,7 +1356,7 @@
if (parcel != NULL) {
const status_t err = parcel->writeInt32(val);
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1344,7 +1367,7 @@
if (parcel != NULL) {
const status_t err = parcel->writeInt64(val);
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1355,7 +1378,7 @@
if (parcel != NULL) {
const status_t err = parcel->writeFloat(val);
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1366,7 +1389,7 @@
if (parcel != NULL) {
const status_t err = parcel->writeDouble(val);
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1386,7 +1409,7 @@
err = parcel->writeString16(NULL, 0);
}
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1397,7 +1420,7 @@
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1409,7 +1432,7 @@
const status_t err =
parcel->writeDupFileDescriptor(jniGetFDFromFileDescriptor(env, object));
if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ signalExceptionForError(env, clazz, err);
}
}
}
@@ -1717,7 +1740,10 @@
return;
}
- (void) thisParcel->appendFrom(otherParcel, offset, length);
+ status_t err = thisParcel->appendFrom(otherParcel, offset, length);
+ if (err != NO_ERROR) {
+ signalExceptionForError(env, clazz, err);
+ }
}
static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jobject clazz)
@@ -1792,6 +1818,8 @@
{"setDataSize", "(I)V", (void*)android_os_Parcel_setDataSize},
{"setDataPosition", "(I)V", (void*)android_os_Parcel_setDataPosition},
{"setDataCapacity", "(I)V", (void*)android_os_Parcel_setDataCapacity},
+ {"pushAllowFds", "(Z)Z", (void*)android_os_Parcel_pushAllowFds},
+ {"restoreAllowFds", "(Z)V", (void*)android_os_Parcel_restoreAllowFds},
{"writeNative", "([BII)V", (void*)android_os_Parcel_writeNative},
{"writeInt", "(I)V", (void*)android_os_Parcel_writeInt},
{"writeLong", "(J)V", (void*)android_os_Parcel_writeLong},
diff --git a/core/res/res/layout/screen_simple_overlay_action_mode.xml b/core/res/res/layout/screen_simple_overlay_action_mode.xml
new file mode 100644
index 0000000..eb093e7
--- /dev/null
+++ b/core/res/res/layout/screen_simple_overlay_action_mode.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+
+This is an optimized layout for a screen, with the minimum set of features
+enabled.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fitsSystemWindows="true">
+ <FrameLayout
+ android:id="@android:id/content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:foregroundInsidePadding="false"
+ android:foregroundGravity="fill_horizontal|top"
+ android:foreground="?android:attr/windowContentOverlay" />
+ <ViewStub android:id="@+id/action_mode_bar_stub"
+ android:inflatedId="@+id/action_mode_bar"
+ android:layout="@layout/action_mode_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+</FrameLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c990125..a27abb3 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3181,6 +3181,12 @@
<!-- Base text color, typeface, size, and style. -->
<attr name="textAppearance" />
</declare-styleable>
+ <declare-styleable name="SelectionModeDrawables">
+ <attr name="actionModeSelectAllDrawable" />
+ <attr name="actionModeCutDrawable" />
+ <attr name="actionModeCopyDrawable" />
+ <attr name="actionModePasteDrawable" />
+ </declare-styleable>
<declare-styleable name="SuggestionSpan">
<attr name="textUnderlineColor" />
<attr name="textUnderlineThickness" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index b6e213c..13de1c9 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -250,7 +250,7 @@
</style>
<style name="TextAppearance.EasyCorrectSuggestion" parent="TextAppearance.Suggestion">
- <item name="android:textUnderlineColor">#ff888888</item>
+ <item name="android:textUnderlineColor">#ffC8C8C8</item>
</style>
<style name="TextAppearance.MisspelledSuggestion" parent="TextAppearance.Suggestion">
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index 16171dc..9983f38 100755
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -27,17 +27,24 @@
$(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
$(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
$(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \
- $(LOCAL_PATH)/notifications/ogg/Antares.ogg:system/media/audio/notifications/Antares.ogg \
- $(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
- $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
- $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
- $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
$(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
+ $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \
$(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
$(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
+ $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Acheron.ogg:system/media/audio/ringtones/Acheron.ogg \
$(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
$(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
$(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \
$(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \
$(LOCAL_PATH)/ringtones/ogg/Cassiopeia.ogg:system/media/audio/ringtones/Cassiopeia.ogg \
$(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
@@ -45,8 +52,10 @@
$(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \
$(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
$(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Nasqueron.ogg:system/media/audio/ringtones/Nasqueron.ogg \
$(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
$(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
+ $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \
$(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
$(LOCAL_PATH)/ringtones/ogg/Rigel.ogg:system/media/audio/ringtones/Rigel.ogg \
$(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
diff --git a/data/sounds/notifications/ogg/Arcturus.ogg b/data/sounds/notifications/ogg/Arcturus.ogg
new file mode 100644
index 0000000..8b83285
--- /dev/null
+++ b/data/sounds/notifications/ogg/Arcturus.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Capella.ogg b/data/sounds/notifications/ogg/Capella.ogg
new file mode 100755
index 0000000..88a955d
--- /dev/null
+++ b/data/sounds/notifications/ogg/Capella.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/CetiAlpha.ogg b/data/sounds/notifications/ogg/CetiAlpha.ogg
new file mode 100644
index 0000000..cd09526
--- /dev/null
+++ b/data/sounds/notifications/ogg/CetiAlpha.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Polaris.ogg b/data/sounds/notifications/ogg/Polaris.ogg
new file mode 100755
index 0000000..0f63a65
--- /dev/null
+++ b/data/sounds/notifications/ogg/Polaris.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Procyon.ogg b/data/sounds/notifications/ogg/Procyon.ogg
new file mode 100755
index 0000000..e5ffcdb
--- /dev/null
+++ b/data/sounds/notifications/ogg/Procyon.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Vega.ogg b/data/sounds/notifications/ogg/Vega.ogg
new file mode 100644
index 0000000..7cdbf21
--- /dev/null
+++ b/data/sounds/notifications/ogg/Vega.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Acheron.ogg b/data/sounds/ringtones/ogg/Acheron.ogg
new file mode 100644
index 0000000..67d7388
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Acheron.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Nasqueron.ogg b/data/sounds/ringtones/ogg/Nasqueron.ogg
new file mode 100644
index 0000000..ae1a725
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Nasqueron.ogg
Binary files differ
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 464430b..1e3e275 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -101,41 +101,41 @@
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/ui/declaring-layout.html">
- <span class="en">Declaring Layout</span>
- </a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/ui/menus.html">
- <span class="en">Creating Menus</span>
- </a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html">
- <span class="en">Using the Action Bar</span>
- </a></li>
- <li><a href="<?cs var:toroot ?>guide/topics/ui/dialogs.html">
- <span class="en">Creating Dialogs</span>
+ <span class="en">XML Layouts</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/ui-events.html">
- <span class="en">Handling UI Events</span>
+ <span class="en">Input Events</span>
+ </a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/ui/menus.html">
+ <span class="en">Menus</span>
+ </a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html">
+ <span class="en">Action Bar</span>
+ </a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/ui/dialogs.html">
+ <span class="en">Dialogs</span>
</a></li>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/index.html">
- <span class="en">Notifying the User</span>
+ <span class="en">Notifications</span>
</a></div>
<ul>
<li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/toasts.html">
- <span class="en">Creating Toast Notifications</span>
+ <span class="en">Toast Notifications</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/notifications.html">
- <span class="en">Creating Status Bar Notifications</span>
+ <span class="en">Status Bar Notifications</span>
</a></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/drag-drop.html">
- <span class="en">Dragging and Dropping</span>
+ <span class="en">Drag and Drop</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/themes.html">
- <span class="en">Applying Styles and Themes</span>
+ <span class="en">Styles and Themes</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/custom-components.html">
- <span class="en">Building Custom Components</span>
+ <span class="en">Custom Components</span>
</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/ui/binding.html">
<span class="en">Binding to Data with AdapterView</span>
diff --git a/docs/html/guide/practices/design/seamlessness.jd b/docs/html/guide/practices/design/seamlessness.jd
index dedc16f..6c73426 100644
--- a/docs/html/guide/practices/design/seamlessness.jd
+++ b/docs/html/guide/practices/design/seamlessness.jd
@@ -171,7 +171,7 @@
avoid rolling your own as much as possible. Instead, use a Theme. You
can override or extend those parts of the theme that you need to, but at least
you're starting from the same UI base as all the other applications. For all
-the details, read <a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p>
+the details, read <a href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.</p>
<h2 id="flexui">Design Your UI to Work with Multiple Screen Resolutions</h2>
diff --git a/docs/html/guide/practices/ui_guidelines/menu_design.jd b/docs/html/guide/practices/ui_guidelines/menu_design.jd
index 7751a7b..3edf33f 100644
--- a/docs/html/guide/practices/ui_guidelines/menu_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/menu_design.jd
@@ -260,8 +260,8 @@
<img src={@docRoot}images/menu_design/TaskFlowDiagram.png>
<p>
- For more technical information on menus, see
- <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>.
+ For more technical information on menus, see the
+ <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide.
</p>
<h3 id="commands_fixed">Commands Fixed in an Activity Screen</h4>
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index 22283cd..20ce701 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -297,8 +297,7 @@
<p>Creating the App Widget layout is simple if you're
familiar with <a
-href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout in
-XML</a>.
+href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a>.
However, you must be aware that App Widget layouts are based on {@link
android.widget.RemoteViews},
which do not support every kind of layout or view widget.</p>
diff --git a/docs/html/guide/topics/fundamentals/fragments.jd b/docs/html/guide/topics/fundamentals/fragments.jd
index 3908a7c..8f61945 100644
--- a/docs/html/guide/topics/fundamentals/fragments.jd
+++ b/docs/html/guide/topics/fundamentals/fragments.jd
@@ -631,8 +631,9 @@
handle the selected item, then the event is passed to the fragment's callback. This is true for
the Options Menu and context menus.</p>
-<p>For more information about menus, see <a href="{@docRoot}guide/topics/ui/menus.html">Creating
-Menus</a> and <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action Bar</a>.</p>
+<p>For more information about menus, see the <a
+href="{@docRoot}guide/topics/ui/menus.html">Menus</a> and <a
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guides.</p>
diff --git a/docs/html/guide/topics/graphics/index.jd b/docs/html/guide/topics/graphics/index.jd
index 2490e39..f0a923a 100644
--- a/docs/html/guide/topics/graphics/index.jd
+++ b/docs/html/guide/topics/graphics/index.jd
@@ -150,7 +150,7 @@
<p class="note"><strong>Note: </strong> In order to request an invalidate from a thread other than your main
Activity's thread, you must call <code>{@link android.view.View#postInvalidate()}</code>.</p>
-<p>Also read <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>
+<p>Also read <a href="{@docRoot}guide/topics/ui/custom-components.html">Custom Components</a>
for a guide to extending a View class, and <a href="2d-graphics.html">2D Graphics: Drawables</a> for
information on using Drawable objects like images from your resources and other primitive shapes.</p>
diff --git a/docs/html/guide/topics/resources/layout-resource.jd b/docs/html/guide/topics/resources/layout-resource.jd
index b069521..286e3d1 100644
--- a/docs/html/guide/topics/resources/layout-resource.jd
+++ b/docs/html/guide/topics/resources/layout-resource.jd
@@ -7,7 +7,7 @@
<div id="qv">
<h2>See also</h2>
<ol>
- <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a></li>
</ol>
</div>
</div>
@@ -127,8 +127,9 @@
</dl>
<p>More attributes are supported by the {@link android.view.View}
base class, and many more are supported by each implementation of
- {@link android.view.View}. Read <a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring
- Layout</a> for more information. For a reference of all available attributes,
+ {@link android.view.View}. Read <a
+href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> for more information. For
+a reference of all available attributes,
see the corresponding reference documentation (for example, the <a
href="{@docRoot}reference/android/widget/TextView.html#lattrs">TextView XML attributes</a>).</p>
</dd>
@@ -235,7 +236,8 @@
<p>You can create your own custom {@link android.view.View} and {@link android.view.ViewGroup}
elements and apply them to your layout the same as a standard layout
element. You can also specify the attributes supported in the XML element. To learn more,
-read <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>.
+see the <a href="{@docRoot}guide/topics/ui/custom-components.html">Custom Components</a> developer
+guide.
</p>
</dd> <!-- end elements and attributes -->
@@ -273,7 +275,7 @@
<dt>see also:</dt>
<dd>
<ul>
- <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a></li>
<li>{@link android.view.View}</li>
<li>{@link android.view.ViewGroup}</li>
</ul>
diff --git a/docs/html/guide/topics/resources/localization.jd b/docs/html/guide/topics/resources/localization.jd
index 36e12f6..9affb15 100755
--- a/docs/html/guide/topics/resources/localization.jd
+++ b/docs/html/guide/topics/resources/localization.jd
@@ -52,7 +52,7 @@
<li><a
href="{@docRoot}resources/tutorials/localization/index.html">Hello, L10N Tutorial</a></li>
<li><a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a></li>
- <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a></li>
<li><a href="{@docRoot}reference/android/app/Activity.html#ActivityLifecycle">Activity Lifecycle</a></li>
</ol>
</div>
diff --git a/docs/html/guide/topics/resources/menu-resource.jd b/docs/html/guide/topics/resources/menu-resource.jd
index 5b90ce2..64cdf21 100644
--- a/docs/html/guide/topics/resources/menu-resource.jd
+++ b/docs/html/guide/topics/resources/menu-resource.jd
@@ -7,7 +7,7 @@
<div id="qv">
<h2>See also</h2>
<ol>
- <li><a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/menus.html">Menus</a></li>
</ol>
</div>
</div>
@@ -15,8 +15,8 @@
<p>A menu resource defines an application menu (Options Menu, Context Menu, or submenu) that
can be inflated with {@link android.view.MenuInflater}.</p>
-<p>For a guide to using menus, see the <a href="{@docRoot}guide/topics/ui/menus.html">Creating
-Menus</a> document.</p>
+<p>For a guide to using menus, see the <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a>
+developer guide.</p>
<dl class="xml">
@@ -132,22 +132,22 @@
bar. Setting multiple items to always appear as action items can result in them overlapping
with other UI in the action bar.</td></tr>
</table>
- <p>See <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action Bar</a> for
-more information.</p>
+ <p>See the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer
+guide for more information.</p>
<p>Introduced in API Level 11.</p>
</dd>
<dt><code>android:actionViewLayout</code></dt>
<dd><em>Layout resource</em>. A layout to use as the action view.
- <p>See <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action Bar</a> for
-more information.</p>
+ <p>See the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer
+guide for more information.</p>
<p>Introduced in API Level 11.</p></dd>
<dt><code>android:actionViewClassName</code></dt>
<dd><em>Class name</em>. A fully-qualified class name for the {@link android.view.View}
to use as the action view.
- <p>See <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action Bar</a> for
-more information.</p>
+ <p>See the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer
+guide for more information.</p>
<p class="warning"><strong>Warning:</strong> If you obfuscate your code using <a
href="{@docRoot}guide/developing/tools/proguard.html">ProGuard</a> (or a similar tool),
be sure to exclude the class you specify in this attribute from renaming, because it can break the
diff --git a/docs/html/guide/topics/resources/style-resource.jd b/docs/html/guide/topics/resources/style-resource.jd
index def727c..f6252dba 100644
--- a/docs/html/guide/topics/resources/style-resource.jd
+++ b/docs/html/guide/topics/resources/style-resource.jd
@@ -7,7 +7,7 @@
<div id="qv">
<h2>See also</h2>
<ol>
- <li><a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a></li>
</ol>
</div>
</div>
@@ -18,7 +18,7 @@
an entire {@link android.app.Activity} or application (from within the manifest file).</p>
<p>For more information about creating and applying styles, please read
-<a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p>
+<a href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.</p>
<p class="note"><strong>Note:</strong> A style is a simple resource that is referenced
using the value provided in the {@code name} attribute (not the name of the XML file). As
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index d869a44..27409d5 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -748,8 +748,8 @@
documentation for {@link android.widget.SearchView} and its nested interfaces for the
appropriate event listeners.</p>
-<p>For more information about action views in the Action Bar, read <a
-href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">Using the Action Bar</a> (which
+<p>For more information about action views in the Action Bar, read the <a
+href="{@docRoot}guide/topics/ui/actionbar.html#ActionView">Action Bar</a> developer guide (which
includes sample code for adding a search widget as an action view).</p>
@@ -803,8 +803,8 @@
android.app.Activity#onSearchRequested onSearchRequested()}.</p>
<p>For more information about how items in the Action Bar work and how to handle this situation, see
-the documentation for <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action
-Bar</a>.</p>
+the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
+Bar</a> developer guide.</p>
<p>Also see the <a
href="{@docRoot}resources/samples/SearchableDictionary/src/com/example/android/searchabledict/
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index 6f12b95..4742923 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -1,4 +1,4 @@
-page.title=Using the Action Bar
+page.title=Action Bar
parent.title=User Interface
parent.link=index.html
@jd:body
@@ -49,7 +49,7 @@
<h2>See also</h2>
<ol>
- <li><a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/menus.html">Menus</a></li>
</ol>
</div>
</div>
@@ -157,7 +157,7 @@
<p>When the activity first starts, the system populates the Action Bar and overflow menu by calling
{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} for your activity. As
-discussed in the guide to <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>, it's in
+discussed in the <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guid, it's in
this callback method that you define the Options Menu for the activity.</p>
<p>You can specify a menu item to appear as an action item—if there is room
@@ -211,7 +211,7 @@
collide with other elements in the Action Bar.</p>
<p>For more information about menus, see the <a
-href="{@docRoot}guide/topics/ui/menus.html#options-menu">Creating Menus</a> developer guide.</p>
+href="{@docRoot}guide/topics/ui/menus.html#options-menu">Menus</a> developer guide.</p>
<h3 id="Home">Using the app icon as an action item</h3>
@@ -845,7 +845,7 @@
</dl>
<p>For more information about using themes in your application, read <a
-href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p>
+href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.</p>
diff --git a/docs/html/guide/topics/ui/custom-components.jd b/docs/html/guide/topics/ui/custom-components.jd
index 900e08b..be82dbc 100644
--- a/docs/html/guide/topics/ui/custom-components.jd
+++ b/docs/html/guide/topics/ui/custom-components.jd
@@ -1,4 +1,4 @@
-page.title=Building Custom Components
+page.title=Custom Components
parent.title=User Interface
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index 4a574be..4dc915f 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -1,4 +1,4 @@
-page.title=Declaring Layout
+page.title=XML Layouts
parent.title=User Interface
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd
index c1272b6..16f14cb 100644
--- a/docs/html/guide/topics/ui/dialogs.jd
+++ b/docs/html/guide/topics/ui/dialogs.jd
@@ -1,4 +1,4 @@
-page.title=Creating Dialogs
+page.title=Dialogs
parent.title=User Interface
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/ui/drag-drop.jd b/docs/html/guide/topics/ui/drag-drop.jd
index 0329c192..93753cc 100644
--- a/docs/html/guide/topics/ui/drag-drop.jd
+++ b/docs/html/guide/topics/ui/drag-drop.jd
@@ -1,4 +1,4 @@
-page.title=Dragging and Dropping
+page.title=Drag and Drop
parent.title=User Interface
parent.link=index.html
@jd:body
@@ -107,7 +107,7 @@
<a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
</li>
<li>
- <a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a>
+ <a href="{@docRoot}guide/topics/ui/ui-events.html">Input Events</a>
</li>
</ol>
</div>
diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd
index 375c9fe..d3060c5 100644
--- a/docs/html/guide/topics/ui/index.jd
+++ b/docs/html/guide/topics/ui/index.jd
@@ -9,7 +9,7 @@
<li><a href="#ViewHierarchy">View Hierarchy</a></li>
<li><a href="#Layout">Layout</a></li>
<li><a href="#Widgets">Widgets</a></li>
- <li><a href="#Events">UI Events</a></li>
+ <li><a href="#Events">Input Events</a></li>
<li><a href="#Menus">Menus</a></li>
<li><a href="#Advanced">Advanced Topics</a>
<ol>
@@ -104,7 +104,7 @@
another LinearLayout (or other type of view group) inside here, to lengthen the view hierarchy and create a more
complex layout.</p>
-<p>For more on building a UI layout, read <a href="declaring-layout.html">Declaring Layout</a>.
+<p>For more on building a UI layout, read <a href="declaring-layout.html">XML Layouts</a>.
<div class="sidebox-wrapper">
<div class="sidebox">
@@ -132,16 +132,16 @@
But you're not limited to the kinds of widgets provided by the Android platform. If you'd
like to do something more customized and create your own actionable elements, you can, by defining your own
View object or by extending and combining existing widgets.</p>
-<p>Read more in <a href="custom-components.html">Building Custom Components</a>.</p>
+<p>Read more in the <a href="custom-components.html">Custom Components</a> developer guide.</p>
<p>For a list of the widgets provided by Android, see the {@link android.widget} package.</p>
-<h2 id="Events">UI Events</h2>
+<h2 id="Events">Input Events</h2>
<p>Once you've added some Views/widgets to the UI, you probably want to know about the
-user's interaction with them, so you can perform actions. To be informed of UI events, you need to
-do one of two things:</p>
+user's interaction with them, so you can perform actions. To be informed of user input events, you
+need to do one of two things:</p>
<ul>
<li><strong>Define an event listener and register it with the View.</strong> More often than not,
this is how you'll listen for events. The View class contains a collection of nested interfaces named
@@ -166,8 +166,8 @@
</li>
</ul>
-<p>Continue reading about handling user interaction with Views in the <a href="ui-events.html">Handling UI Events</a>
-document.</p>
+<p>Continue reading about handling user interaction with Views in the <a
+href="ui-events.html">Input Events</a> document.</p>
<h2 id="Menus">Menus</h2>
@@ -192,7 +192,7 @@
<p>And just like your application layout, you have the option to declare the items for you menu in an XML file.</p>
-<p>Read <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a> to learn more.</p>
+<p>Read <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> to learn more.</p>
<h2 id="Advanced">Advanced Topics</h2>
@@ -232,4 +232,4 @@
<p>Styles and themes are resources. Android provides some default style and theme resources that you can use,
or you can declare your own custom style and theme resources.</p>
<p>Learn more about using styles and themes in the
-<a href="themes.html">Applying Styles and Themes</a> document.</p>
+<a href="themes.html">Styles and Themes</a> document.</p>
diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd
index 984bf8f..2948244 100644
--- a/docs/html/guide/topics/ui/menus.jd
+++ b/docs/html/guide/topics/ui/menus.jd
@@ -1,4 +1,4 @@
-page.title=Creating Menus
+page.title=Menus
parent.title=User Interface
parent.link=index.html
@jd:body
@@ -36,7 +36,7 @@
<h2>See also</h2>
<ol>
- <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action Bar</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a></li>
<li><a href="{@docRoot}guide/topics/resources/menu-resource.html">Menu Resource</a></li>
</ol>
</div>
@@ -301,8 +301,8 @@
items in the Options Menu. If you want to provide menu items that are context-sensitive to a {@link
android.view.View}, use a <a href="#context-menu">Context Menu</a>.</p>
-<p>If you're developing for Android 3.0 or higher, be sure to also read <a
-href="{@docRoot}guide/topics/ui/actionbar.html">Using the Action Bar</a>.</p>
+<p>If you're developing for Android 3.0 or higher, be sure to also read the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> developer guide.</p>
diff --git a/docs/html/guide/topics/ui/notifiers/index.jd b/docs/html/guide/topics/ui/notifiers/index.jd
index 8fc57fc..c61d4f0 100644
--- a/docs/html/guide/topics/ui/notifiers/index.jd
+++ b/docs/html/guide/topics/ui/notifiers/index.jd
@@ -1,19 +1,8 @@
-page.title=Notifying the User
+page.title=Notifications
parent.title=User Interface
parent.link=../index.html
@jd:body
-<div id="qv-wrapper">
- <div id="qv">
- <h2>Topics</h2>
- <ol>
- <li><a href="toasts.html">Creating Toast Notifications</a></li>
- <li><a href="notifications.html">Creating Status Bar Notifications</a></li>
- <li><a href="{@docRoot}guide/topics/ui/dialogs.html">Creating Dialogs</a></li>
- </ol>
- </div>
-</div>
-
<p>Several types of situations may arise that require you to notify the user
about an event that occurs in your application. Some events require the user to respond
and others do not. For example:</p>
@@ -57,7 +46,7 @@
the user to respond and take action, consider using a
<a href="#StatusBar">Status Bar Notification</a> instead.</p>
-<p>For more information, refer to <a href="toasts.html">Creating Toast Notifications</a>.</p>
+<p>For more information, refer to <a href="toasts.html">Toast Notifications</a>.</p>
<h2 id="StatusBar">Status Bar Notification</h2>
@@ -79,7 +68,7 @@
<a href="#Dialog">Dialog Notification</a> instead.</p>
<p>For more information, refer to
-<a href="notifications.html">Creating Status Bar Notifications</a>.</p>
+<a href="notifications.html">Status Bar Notifications</a>.</p>
<h2 id="Dialog">Dialog Notification</h2>
@@ -97,7 +86,7 @@
in your application's UI and for other purposes besides notifications.
For a complete discussion on all the available types of dialogs,
including its uses for notifications, refer to
-<a href="{@docRoot}guide/topics/ui/dialogs.html">Creating Dialogs</a>.</p>
+<a href="{@docRoot}guide/topics/ui/dialogs.html">Dialogs</a>.</p>
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index f12c5ee..7bc1cde 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -1,5 +1,5 @@
-page.title=Creating Status Bar Notifications
-parent.title=Notifying the User
+page.title=Status Bar Notifications
+parent.title=Notifications
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/ui/notifiers/toasts.jd b/docs/html/guide/topics/ui/notifiers/toasts.jd
index 0d3e10c..1a1fb1f 100644
--- a/docs/html/guide/topics/ui/notifiers/toasts.jd
+++ b/docs/html/guide/topics/ui/notifiers/toasts.jd
@@ -1,5 +1,5 @@
-page.title=Creating Toast Notifications
-parent.title=Notifying the User
+page.title=Toast Notifications
+parent.title=Notifications
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/ui/themes.jd b/docs/html/guide/topics/ui/themes.jd
index a213bea..d787492 100644
--- a/docs/html/guide/topics/ui/themes.jd
+++ b/docs/html/guide/topics/ui/themes.jd
@@ -1,4 +1,4 @@
-page.title=Applying Styles and Themes
+page.title=Styles and Themes
parent.title=User Interface
parent.link=index.html
@jd:body
diff --git a/docs/html/guide/topics/ui/ui-events.jd b/docs/html/guide/topics/ui/ui-events.jd
index 7d7bfaf..93bad43 100644
--- a/docs/html/guide/topics/ui/ui-events.jd
+++ b/docs/html/guide/topics/ui/ui-events.jd
@@ -1,4 +1,4 @@
-page.title=Handling UI Events
+page.title=Input Events
parent.title=User Interface
parent.link=index.html
@jd:body
@@ -72,7 +72,8 @@
<dt><code>onCreateContextMenu()</code></dt>
<dd>From {@link android.view.View.OnCreateContextMenuListener}.
This is called when a Context Menu is being built (as the result of a sustained "long click"). See the discussion
- on context menus in <a href="{@docRoot}guide/topics/ui/menus.html#context-menu">Creating Menus</a> for more information.</dd>
+ on context menus in the <a href="{@docRoot}guide/topics/ui/menus.html#context-menu">Menus</a>
+ developer guide.</dd>
</dl>
<p>These methods are the sole inhabitants of their respective interface. To define one of these methods
@@ -159,8 +160,9 @@
<p>If you're building a custom component from View, then you'll be able to define several callback methods
used as default event handlers.
-In the document on <a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>,
-you'll learn see some of the common callbacks used for event handling, including:</p>
+In the document about <a href="{@docRoot}guide/topics/ui/custom-components.html">Custom
+Components</a>, you'll learn see some of the common callbacks used for event handling,
+including:</p>
<ul>
<li><code>{@link android.view.View#onKeyDown}</code> - Called when a new key event occurs.</li>
<li><code>{@link android.view.View#onKeyUp}</code> - Called when a key up event occurs.</li>
diff --git a/docs/html/guide/tutorials/notepad/notepad-ex2.jd b/docs/html/guide/tutorials/notepad/notepad-ex2.jd
index 854731f..fed40ab 100644
--- a/docs/html/guide/tutorials/notepad/notepad-ex2.jd
+++ b/docs/html/guide/tutorials/notepad/notepad-ex2.jd
@@ -299,7 +299,8 @@
in real Android applications.</p>
<p>Creating a
good UI is part art and part science, and the rest is work. Mastery of <a
- href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a> is an essential part of creating
+ href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> is an essential part of
+creating
a good looking Android application.</p>
<p>Take a look at the
<a href="{@docRoot}resources/tutorials/views/index.html">Hello Views</a>
diff --git a/docs/html/resources/faq/commontasks.jd b/docs/html/resources/faq/commontasks.jd
index b211db0..c72343a0 100644
--- a/docs/html/resources/faq/commontasks.jd
+++ b/docs/html/resources/faq/commontasks.jd
@@ -268,7 +268,8 @@
{@link android.app.Activity#finishActivity(int) Activity.finishActivity()}
on any screens that it opens to close them. </p>
<a name="listening" id="listening"></a><h2>Listening for Button Clicks</h2>
-<p>Button click and other UI event capturing are covered in <a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a> on the UI Design page.</p>
+<p>Button click and other UI event capturing are covered in <a
+href="{@docRoot}guide/topics/ui/ui-events.html">Input Events</a>.</p>
<a name="configurewindowproperties" id="configurewindowproperties"></a><h2>Configuring General Window Properties</h2>
<p>You can set a number of general window properties, such as whether to display
a title, whether the window is floating, and whether it displays an icon, by
@@ -543,7 +544,7 @@
which enables a dialog box with an embedded progress bar to send a "I'm working
on it" notification to the user. </p>
<a name="addmenuitems" id="addmenuitems"></a><h2>Adding Items to the Screen Menu</h2>
-<p>See <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>.</p>
+<p>See <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a>.</p>
<a name="webpage" id="webpage"></a><h2>Display a Web Page</h2>
<p>Use the {@link android.webkit.WebView webkit.WebView} object. </p>
diff --git a/docs/html/resources/tutorials/notepad/notepad-ex2.jd b/docs/html/resources/tutorials/notepad/notepad-ex2.jd
index 499b796..7e3288f1 100644
--- a/docs/html/resources/tutorials/notepad/notepad-ex2.jd
+++ b/docs/html/resources/tutorials/notepad/notepad-ex2.jd
@@ -299,7 +299,8 @@
in real Android applications.</p>
<p>Creating a
good UI is part art and part science, and the rest is work. Mastery of <a
- href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a> is an essential part of creating
+ href="{@docRoot}guide/topics/ui/declaring-layout.html">XML Layouts</a> is an essential part of
+creating
a good looking Android application.</p>
<p>Take a look at the
<a href="{@docRoot}resources/tutorials/views/index.html">Hello Views</a>
diff --git a/docs/html/search.jd b/docs/html/search.jd
index 339ce2d..407bc86 100644
--- a/docs/html/search.jd
+++ b/docs/html/search.jd
@@ -64,11 +64,14 @@
// upon ajax search, refresh the url and search title
searchControl.setSearchStartingCallback(this, function(control, searcher, query) {
+ $("#searchTitle").html("search results for <em>" + escapeHTML(query) + "</em>");
+
// save the tab index from the hash
tabIndex = location.hash.split("&t=")[1];
-
- $("#searchTitle").html("search results for <em>" + escapeHTML(query) + "</em>");
$.history.add('q=' + query + '&t=' + tabIndex);
+ });
+
+ searchControl.setSearchCompleteCallback(this, function(control, searcher) {
openTab();
});
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index bfe13f0..3fa2acb 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -38,6 +38,9 @@
class Parcel
{
public:
+ class ReadableBlob;
+ class WritableBlob;
+
Parcel();
~Parcel();
@@ -46,7 +49,7 @@
size_t dataAvail() const;
size_t dataPosition() const;
size_t dataCapacity() const;
-
+
status_t setDataSize(size_t size);
void setDataPosition(size_t pos) const;
status_t setDataCapacity(size_t size);
@@ -56,6 +59,9 @@
status_t appendFrom(const Parcel *parcel,
size_t start, size_t len);
+ bool pushAllowFds(bool allowFds);
+ void restoreAllowFds(bool lastValue);
+
bool hasFileDescriptors() const;
// Writes the RPC header.
@@ -109,7 +115,13 @@
// Place a file descriptor into the parcel. A dup of the fd is made, which
// will be closed once the parcel is destroyed.
status_t writeDupFileDescriptor(int fd);
-
+
+ // Writes a blob to the parcel.
+ // If the blob is small, then it is stored in-place, otherwise it is
+ // transferred by way of an anonymous shared memory region.
+ // The caller should call release() on the blob after writing its contents.
+ status_t writeBlob(size_t len, WritableBlob* outBlob);
+
status_t writeObject(const flat_binder_object& val, bool nullMetaData);
// Like Parcel.java's writeNoException(). Just writes a zero int32.
@@ -157,7 +169,11 @@
// Retrieve a file descriptor from the parcel. This returns the raw fd
// in the parcel, which you do not own -- use dup() to get your own copy.
int readFileDescriptor() const;
-
+
+ // Reads a blob from the parcel.
+ // The caller should call release() on the blob after reading its contents.
+ status_t readBlob(size_t len, ReadableBlob* outBlob) const;
+
const flat_binder_object* readObject(bool nullMetaData) const;
// Explicitly close all file descriptors in the parcel.
@@ -177,7 +193,7 @@
release_func relFunc, void* relCookie);
void print(TextOutput& to, uint32_t flags = 0) const;
-
+
private:
Parcel(const Parcel& o);
Parcel& operator=(const Parcel& o);
@@ -212,9 +228,40 @@
mutable bool mFdsKnown;
mutable bool mHasFds;
+ bool mAllowFds;
release_func mOwner;
void* mOwnerCookie;
+
+ class Blob {
+ public:
+ Blob();
+ ~Blob();
+
+ void release();
+ inline size_t size() const { return mSize; }
+
+ protected:
+ void init(bool mapped, void* data, size_t size);
+ void clear();
+
+ bool mMapped;
+ void* mData;
+ size_t mSize;
+ };
+
+public:
+ class ReadableBlob : public Blob {
+ friend class Parcel;
+ public:
+ inline const void* data() const { return mData; }
+ };
+
+ class WritableBlob : public Blob {
+ friend class Parcel;
+ public:
+ inline void* data() { return mData; }
+ };
};
// ---------------------------------------------------------------------------
diff --git a/include/utils/Errors.h b/include/utils/Errors.h
index 81f818b..0b75b19 100644
--- a/include/utils/Errors.h
+++ b/include/utils/Errors.h
@@ -72,6 +72,7 @@
TIMED_OUT = 0x80000005,
UNKNOWN_TRANSACTION = 0x80000006,
#endif
+ FDS_NOT_ALLOWED = 0x80000007,
};
// Restore define; enumeration is in "android" namespace, so the value defined
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a0fc4d0..608877e 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -30,12 +30,14 @@
#include <utils/TextOutput.h>
#include <utils/misc.h>
#include <utils/Flattenable.h>
+#include <cutils/ashmem.h>
#include <private/binder/binder_module.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#include <sys/mman.h>
#ifndef INT32_MAX
#define INT32_MAX ((int32_t)(2147483647))
@@ -54,6 +56,9 @@
// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
#define EX_HAS_REPLY_HEADER -128
+// Maximum size of a blob to transfer in-place.
+static const size_t IN_PLACE_BLOB_LIMIT = 40 * 1024;
+
// XXX This can be made public if we want to provide
// support for typed data.
struct small_flat_data
@@ -399,6 +404,8 @@
mDataPos += len;
mDataSize += len;
+ err = NO_ERROR;
+
if (numObjects > 0) {
// grow objects
if (mObjectsCapacity < mObjectsSize + numObjects) {
@@ -430,11 +437,28 @@
flat->handle = dup(flat->handle);
flat->cookie = (void*)1;
mHasFds = mFdsKnown = true;
+ if (!mAllowFds) {
+ err = FDS_NOT_ALLOWED;
+ }
}
}
}
- return NO_ERROR;
+ return err;
+}
+
+bool Parcel::pushAllowFds(bool allowFds)
+{
+ const bool origValue = mAllowFds;
+ if (!allowFds) {
+ mAllowFds = false;
+ }
+ return origValue;
+}
+
+void Parcel::restoreAllowFds(bool lastValue)
+{
+ mAllowFds = lastValue;
}
bool Parcel::hasFileDescriptors() const
@@ -706,6 +730,54 @@
return writeObject(obj, true);
}
+status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
+{
+ status_t status;
+
+ if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
+ LOGV("writeBlob: write in place");
+ status = writeInt32(0);
+ if (status) return status;
+
+ void* ptr = writeInplace(len);
+ if (!ptr) return NO_MEMORY;
+
+ outBlob->init(false /*mapped*/, ptr, len);
+ return NO_ERROR;
+ }
+
+ LOGV("writeBlob: write to ashmem");
+ int fd = ashmem_create_region("Parcel Blob", len);
+ if (fd < 0) return NO_MEMORY;
+
+ int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
+ if (result < 0) {
+ status = -result;
+ } else {
+ void* ptr = ::mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ status = -errno;
+ } else {
+ result = ashmem_set_prot_region(fd, PROT_READ);
+ if (result < 0) {
+ status = -result;
+ } else {
+ status = writeInt32(1);
+ if (!status) {
+ status = writeFileDescriptor(fd);
+ if (!status) {
+ outBlob->init(true /*mapped*/, ptr, len);
+ return NO_ERROR;
+ }
+ }
+ }
+ }
+ ::munmap(ptr, len);
+ }
+ ::close(fd);
+ return status;
+}
+
status_t Parcel::write(const Flattenable& val)
{
status_t err;
@@ -759,6 +831,9 @@
// remember if it's a file descriptor
if (val.type == BINDER_TYPE_FD) {
+ if (!mAllowFds) {
+ return FDS_NOT_ALLOWED;
+ }
mHasFds = mFdsKnown = true;
}
@@ -1025,6 +1100,32 @@
return BAD_TYPE;
}
+status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
+{
+ int32_t useAshmem;
+ status_t status = readInt32(&useAshmem);
+ if (status) return status;
+
+ if (!useAshmem) {
+ LOGV("readBlob: read in place");
+ const void* ptr = readInplace(len);
+ if (!ptr) return BAD_VALUE;
+
+ outBlob->init(false /*mapped*/, const_cast<void*>(ptr), len);
+ return NO_ERROR;
+ }
+
+ LOGV("readBlob: read from ashmem");
+ int fd = readFileDescriptor();
+ if (fd == int(BAD_TYPE)) return BAD_VALUE;
+
+ void* ptr = ::mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
+ if (!ptr) return NO_MEMORY;
+
+ outBlob->init(true /*mapped*/, ptr, len);
+ return NO_ERROR;
+}
+
status_t Parcel::read(Flattenable& val) const
{
// size
@@ -1283,6 +1384,7 @@
mNextObjectHint = 0;
mHasFds = false;
mFdsKnown = true;
+ mAllowFds = true;
return NO_ERROR;
}
@@ -1434,6 +1536,7 @@
mNextObjectHint = 0;
mHasFds = false;
mFdsKnown = true;
+ mAllowFds = true;
mOwner = NULL;
}
@@ -1452,4 +1555,33 @@
mFdsKnown = true;
}
+// --- Parcel::Blob ---
+
+Parcel::Blob::Blob() :
+ mMapped(false), mData(NULL), mSize(0) {
+}
+
+Parcel::Blob::~Blob() {
+ release();
+}
+
+void Parcel::Blob::release() {
+ if (mMapped && mData) {
+ ::munmap(mData, mSize);
+ }
+ clear();
+}
+
+void Parcel::Blob::init(bool mapped, void* data, size_t size) {
+ mMapped = mapped;
+ mData = data;
+ mSize = size;
+}
+
+void Parcel::Blob::clear() {
+ mMapped = false;
+ mData = NULL;
+ mSize = 0;
+}
+
}; // namespace android
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 886997c..c25e3ca 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -147,8 +147,16 @@
*/
private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
+ /** The stream type that the lock sounds are tied to. */
+ private static final int MASTER_STREAM_TYPE = AudioManager.STREAM_RING;
+ /** Minimum volume for lock sounds, as a ratio of max MASTER_STREAM_TYPE */
+ final float MIN_LOCK_VOLUME = 0.05f;
+ /** Maximum volume for lock sounds, as a ratio of max MASTER_STREAM_TYPE */
+ final float MAX_LOCK_VOLUME = 0.4f;
+
private Context mContext;
private AlarmManager mAlarmManager;
+ private AudioManager mAudioManager;
private StatusBarManager mStatusBarManager;
private boolean mShowLockIcon;
private boolean mShowingLockIcon;
@@ -255,6 +263,7 @@
private int mLockSoundId;
private int mUnlockSoundId;
private int mLockSoundStreamId;
+ private int mMasterStreamMaxVolume;
public KeyguardViewMediator(Context context, PhoneWindowManager callback,
LocalPowerManager powerManager) {
@@ -1061,13 +1070,33 @@
}
final ContentResolver cr = mContext.getContentResolver();
- if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1)
- {
+ if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
final int whichSound = locked
? mLockSoundId
: mUnlockSoundId;
mLockSounds.stop(mLockSoundStreamId);
- mLockSoundStreamId = mLockSounds.play(whichSound, 1.0f, 1.0f, 1, 0, 1.0f);
+ // Init mAudioManager
+ if (mAudioManager == null) {
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ if (mAudioManager == null) return;
+ mMasterStreamMaxVolume = mAudioManager.getStreamMaxVolume(MASTER_STREAM_TYPE);
+ }
+ // If the stream is muted, don't play the sound
+ if (mAudioManager.isStreamMute(MASTER_STREAM_TYPE)) return;
+
+ // Adjust the lock sound volume from a minimum of MIN_LOCK_VOLUME to a maximum
+ // of MAX_LOCK_VOLUME, relative to the maximum level of the MASTER_STREAM_TYPE volume.
+ float lockSoundVolume;
+ int masterStreamVolume = mAudioManager.getStreamVolume(MASTER_STREAM_TYPE);
+ if (masterStreamVolume == 0) {
+ return;
+ } else {
+ lockSoundVolume = MIN_LOCK_VOLUME + (MAX_LOCK_VOLUME - MIN_LOCK_VOLUME)
+ * ((float) masterStreamVolume / mMasterStreamMaxVolume);
+ }
+
+ mLockSoundStreamId = mLockSounds.play(whichSound, lockSoundVolume, lockSoundVolume, 1,
+ 0, 1.0f);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index f970ff3..ca5d274 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -531,7 +531,8 @@
((KeyguardScreen) mUnlockScreen).onResume();
}
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
} else {
mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
@@ -1014,7 +1015,8 @@
// Binds to FaceLock service, but does not tell it to start
public void bindToFaceLock() {
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
if (!mBoundToFaceLockService) {
if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
@@ -1030,7 +1032,8 @@
// Tells FaceLock to stop and then unbinds from the FaceLock service
public void stopAndUnbindFromFaceLock() {
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
stopFaceLock();
if (mBoundToFaceLockService) {
@@ -1079,7 +1082,8 @@
// Tells the FaceLock service to start displaying its UI and perform recognition
public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
{
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
synchronized (mFaceLockServiceRunningLock) {
if (!mFaceLockServiceRunning) {
if (DEBUG) Log.d(TAG, "Starting FaceLock");
@@ -1099,7 +1103,8 @@
// Tells the FaceLock service to stop displaying its UI and stop recognition
public void stopFaceLock()
{
- if (mLockPatternUtils.usingBiometricWeak()) {
+ if (mLockPatternUtils.usingBiometricWeak() &&
+ mLockPatternUtils.isBiometricWeakInstalled()) {
// Note that attempting to stop FaceLock when it's not running is not an issue.
// FaceLock can return, which stops it and then we try to stop it when the
// screen is turned off. That's why we check.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 9205b9a..2cd6eab 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2147,15 +2147,12 @@
mActionMode = mode;
} else {
if (mActionModeView == null) {
- if (hasFeature(FEATURE_ACTION_MODE_OVERLAY)) {
+ if (isFloating()) {
mActionModeView = new ActionBarContextView(mContext);
mActionModePopup = new PopupWindow(mContext, null,
com.android.internal.R.attr.actionModePopupWindowStyle);
mActionModePopup.setLayoutInScreenEnabled(true);
mActionModePopup.setLayoutInsetDecor(true);
- mActionModePopup.setFocusable(true);
- mActionModePopup.setOutsideTouchable(false);
- mActionModePopup.setTouchModal(false);
mActionModePopup.setWindowLayoutType(
WindowManager.LayoutParams.TYPE_APPLICATION);
mActionModePopup.setContentView(mActionModeView);
@@ -2186,7 +2183,8 @@
if (mActionModeView != null) {
mActionModeView.killMode();
- mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback);
+ mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback,
+ mActionModePopup == null);
if (callback.onCreateActionMode(mode, mode.getMenu())) {
mode.invalidate();
mActionModeView.initForMode(mode);
@@ -2664,6 +2662,8 @@
layoutResource = com.android.internal.R.layout.screen_title;
}
// System.out.println("Title!");
+ } else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
+ layoutResource = com.android.internal.R.layout.screen_simple_overlay_action_mode;
} else {
// Embedded, so no decoration is needed.
layoutResource = com.android.internal.R.layout.screen_simple;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 968180c..ed67707 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -276,6 +276,7 @@
int mLidOpenRotation;
int mCarDockRotation;
int mDeskDockRotation;
+ int mHdmiRotation;
int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
int mUserRotation = Surface.ROTATION_0;
@@ -777,6 +778,12 @@
? mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width)
: 0;
+
+ if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
+ mHdmiRotation = mPortraitRotation;
+ } else {
+ mHdmiRotation = mLandscapeRotation;
+ }
}
public void updateSettings() {
@@ -2922,7 +2929,7 @@
int preferredRotation = -1;
if (mHdmiPlugged) {
// Ignore sensor when plugged into HDMI.
- preferredRotation = mLandscapeRotation;
+ preferredRotation = mHdmiRotation;
} else if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
// Ignore sensor when lid switch is open and rotation is forced.
preferredRotation = mLidOpenRotation;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 883fc71..660681b 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -149,6 +149,8 @@
private static final int WIFI_ENABLED = 1;
/* Wifi enabled while in airplane mode */
private static final int WIFI_ENABLED_AIRPLANE_OVERRIDE = 2;
+ /* Wifi disabled due to airplane mode on */
+ private static final int WIFI_DISABLED_AIRPLANE_ON = 3;
private AtomicInteger mWifiState = new AtomicInteger(WIFI_DISABLED);
private AtomicBoolean mAirplaneModeOn = new AtomicBoolean(false);
@@ -478,14 +480,19 @@
private void persistWifiEnabled(boolean enabled) {
final ContentResolver cr = mContext.getContentResolver();
+ boolean airplane = mAirplaneModeOn.get() && isAirplaneToggleable();
if (enabled) {
- if (isAirplaneModeOn() && isAirplaneToggleable()) {
+ if (airplane) {
mWifiState.set(WIFI_ENABLED_AIRPLANE_OVERRIDE);
} else {
mWifiState.set(WIFI_ENABLED);
}
} else {
- mWifiState.set(WIFI_DISABLED);
+ if (airplane) {
+ mWifiState.set(WIFI_DISABLED_AIRPLANE_ON);
+ } else {
+ mWifiState.set(WIFI_DISABLED);
+ }
}
Settings.Secure.putInt(cr, Settings.Secure.WIFI_ON, mWifiState.get());
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index eb135b7..19dd606 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -753,7 +753,7 @@
if (state != null) {
final InstallArgs args = state.getInstallArgs();
- Slog.i(TAG, "Validation timed out for " + args.packageURI.toString());
+ Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
mPendingVerification.remove(verificationId);
int ret = PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT;
@@ -769,7 +769,7 @@
final PackageVerificationState state = mPendingVerification.get(verificationId);
if (state == null) {
- Slog.w(TAG, "Invalid validation token " + verificationId + " received");
+ Slog.w(TAG, "Invalid verification token " + verificationId + " received");
break;
}
@@ -5464,8 +5464,8 @@
final int requiredUid = mRequiredVerifierPackage == null ? -1
: getPackageUid(mRequiredVerifierPackage);
if (requiredUid != -1 && isVerificationEnabled()) {
- final Intent verification = new Intent(
- Intent.ACTION_PACKAGE_NEEDS_VERIFICATION, packageURI);
+ final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+ verification.setDataAndType(packageURI, PACKAGE_MIME_TYPE);
verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
final List<ResolveInfo> receivers = queryIntentReceivers(verification, null,
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 18d6eaa..568a485 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -100,6 +100,7 @@
private static Context sContext;
private static final String TAG = "WifiConfigStore";
+ private static final boolean DBG = false;
/* configured networks with network id as the key */
private static HashMap<Integer, WifiConfiguration> sConfiguredNetworks =
@@ -140,7 +141,7 @@
* and enable all stored networks in supplicant.
*/
static void initialize(Context context) {
- Log.d(TAG, "Loading config and enabling all networks");
+ if (DBG) log("Loading config and enabling all networks");
sContext = context;
loadConfiguredNetworks();
enableAllNetworks();
@@ -173,7 +174,7 @@
networkEnabledStateChanged = true;
config.status = Status.ENABLED;
} else {
- Log.e(TAG, "Enable network failed on " + config.networkId);
+ loge("Enable network failed on " + config.networkId);
}
}
}
@@ -204,7 +205,7 @@
if (netId != INVALID_NETWORK_ID) {
selectNetwork(netId);
} else {
- Log.e(TAG, "Failed to update network " + config);
+ loge("Failed to update network " + config);
}
return netId;
}
@@ -290,7 +291,7 @@
writeIpAndProxyConfigurations();
sendConfiguredNetworksChangedBroadcast();
} else {
- Log.e(TAG, "Failed to remove network " + netId);
+ loge("Failed to remove network " + netId);
}
}
@@ -404,7 +405,7 @@
markAllNetworksDisabled();
result.status = WpsResult.Status.SUCCESS;
} else {
- Log.e(TAG, "Failed to start WPS pin method configuration");
+ loge("Failed to start WPS pin method configuration");
result.status = WpsResult.Status.FAILURE;
}
return result;
@@ -423,7 +424,7 @@
markAllNetworksDisabled();
result.status = WpsResult.Status.SUCCESS;
} else {
- Log.e(TAG, "Failed to start WPS pin method configuration");
+ loge("Failed to start WPS pin method configuration");
result.status = WpsResult.Status.FAILURE;
}
return result;
@@ -439,7 +440,7 @@
markAllNetworksDisabled();
result.status = WpsResult.Status.SUCCESS;
} else {
- Log.e(TAG, "Failed to start WPS push button configuration");
+ loge("Failed to start WPS push button configuration");
result.status = WpsResult.Status.FAILURE;
}
return result;
@@ -680,7 +681,7 @@
/* Ignore */
break;
default:
- Log.e(TAG, "Ignore invalid ip assignment while writing");
+ loge("Ignore invalid ip assignment while writing");
break;
}
@@ -707,7 +708,7 @@
/* Ignore */
break;
default:
- Log.e(TAG, "Ignore invalid proxy settings while writing");
+ loge("Ignore invalid proxy settings while writing");
break;
}
if (writeToFile) {
@@ -715,14 +716,14 @@
out.writeInt(configKey(config));
}
} catch (NullPointerException e) {
- Log.e(TAG, "Failure in writing " + config.linkProperties + e);
+ loge("Failure in writing " + config.linkProperties + e);
}
out.writeUTF(EOS);
}
}
} catch (IOException e) {
- Log.e(TAG, "Error writing data file");
+ loge("Error writing data file");
} finally {
if (out != null) {
try {
@@ -741,7 +742,7 @@
int version = in.readInt();
if (version != 2 && version != 1) {
- Log.e(TAG, "Bad version on IP configuration file, ignore read");
+ loge("Bad version on IP configuration file, ignore read");
return;
}
@@ -797,10 +798,10 @@
} else if (key.equals(EOS)) {
break;
} else {
- Log.e(TAG, "Ignore unknown key " + key + "while reading");
+ loge("Ignore unknown key " + key + "while reading");
}
} catch (IllegalArgumentException e) {
- Log.e(TAG, "Ignore invalid address while reading" + e);
+ loge("Ignore invalid address while reading" + e);
}
} while (true);
@@ -810,7 +811,7 @@
sNetworkIds.get(id));
if (config == null) {
- Log.e(TAG, "configuration found for missing network, ignored");
+ loge("configuration found for missing network, ignored");
} else {
config.linkProperties = linkProperties;
switch (ipAssignment) {
@@ -822,7 +823,7 @@
//Ignore
break;
default:
- Log.e(TAG, "Ignore invalid ip assignment while reading");
+ loge("Ignore invalid ip assignment while reading");
break;
}
@@ -840,18 +841,18 @@
//Ignore
break;
default:
- Log.e(TAG, "Ignore invalid proxy settings while reading");
+ loge("Ignore invalid proxy settings while reading");
break;
}
}
}
} else {
- Log.e(TAG, "Missing id while parsing configuration");
+ loge("Missing id while parsing configuration");
}
}
} catch (EOFException ignore) {
} catch (IOException e) {
- Log.e(TAG, "Error parsing configuration" + e);
+ loge("Error parsing configuration" + e);
} finally {
if (in != null) {
try {
@@ -878,7 +879,7 @@
newNetwork = true;
netId = WifiNative.addNetworkCommand();
if (netId < 0) {
- Log.e(TAG, "Failed to add a network!");
+ loge("Failed to add a network!");
return new NetworkUpdateResult(INVALID_NETWORK_ID);
}
}
@@ -893,7 +894,7 @@
netId,
WifiConfiguration.ssidVarName,
config.SSID)) {
- Log.d(TAG, "failed to set SSID: "+config.SSID);
+ loge("failed to set SSID: "+config.SSID);
break setVariables;
}
@@ -902,7 +903,7 @@
netId,
WifiConfiguration.bssidVarName,
config.BSSID)) {
- Log.d(TAG, "failed to set BSSID: "+config.BSSID);
+ loge("failed to set BSSID: "+config.BSSID);
break setVariables;
}
@@ -913,7 +914,7 @@
netId,
WifiConfiguration.KeyMgmt.varName,
allowedKeyManagementString)) {
- Log.d(TAG, "failed to set key_mgmt: "+
+ loge("failed to set key_mgmt: "+
allowedKeyManagementString);
break setVariables;
}
@@ -925,7 +926,7 @@
netId,
WifiConfiguration.Protocol.varName,
allowedProtocolsString)) {
- Log.d(TAG, "failed to set proto: "+
+ loge("failed to set proto: "+
allowedProtocolsString);
break setVariables;
}
@@ -937,7 +938,7 @@
netId,
WifiConfiguration.AuthAlgorithm.varName,
allowedAuthAlgorithmsString)) {
- Log.d(TAG, "failed to set auth_alg: "+
+ loge("failed to set auth_alg: "+
allowedAuthAlgorithmsString);
break setVariables;
}
@@ -950,7 +951,7 @@
netId,
WifiConfiguration.PairwiseCipher.varName,
allowedPairwiseCiphersString)) {
- Log.d(TAG, "failed to set pairwise: "+
+ loge("failed to set pairwise: "+
allowedPairwiseCiphersString);
break setVariables;
}
@@ -962,7 +963,7 @@
netId,
WifiConfiguration.GroupCipher.varName,
allowedGroupCiphersString)) {
- Log.d(TAG, "failed to set group: "+
+ loge("failed to set group: "+
allowedGroupCiphersString);
break setVariables;
}
@@ -974,7 +975,7 @@
netId,
WifiConfiguration.pskVarName,
config.preSharedKey)) {
- Log.d(TAG, "failed to set psk");
+ loge("failed to set psk");
break setVariables;
}
@@ -988,9 +989,7 @@
netId,
WifiConfiguration.wepKeyVarNames[i],
config.wepKeys[i])) {
- Log.d(TAG,
- "failed to set wep_key"+i+": " +
- config.wepKeys[i]);
+ loge("failed to set wep_key" + i + ": " + config.wepKeys[i]);
break setVariables;
}
hasSetKey = true;
@@ -1003,9 +1002,7 @@
netId,
WifiConfiguration.wepTxKeyIdxVarName,
Integer.toString(config.wepTxKeyIndex))) {
- Log.d(TAG,
- "failed to set wep_tx_keyidx: "+
- config.wepTxKeyIndex);
+ loge("failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
break setVariables;
}
}
@@ -1014,7 +1011,7 @@
netId,
WifiConfiguration.priorityVarName,
Integer.toString(config.priority))) {
- Log.d(TAG, config.SSID + ": failed to set priority: "
+ loge(config.SSID + ": failed to set priority: "
+config.priority);
break setVariables;
}
@@ -1023,7 +1020,7 @@
netId,
WifiConfiguration.hiddenSSIDVarName,
Integer.toString(config.hiddenSSID ? 1 : 0))) {
- Log.d(TAG, config.SSID + ": failed to set hiddenSSID: "+
+ loge(config.SSID + ": failed to set hiddenSSID: "+
config.hiddenSSID);
break setVariables;
}
@@ -1040,7 +1037,7 @@
netId,
varName,
value)) {
- Log.d(TAG, config.SSID + ": failed to set " + varName +
+ loge(config.SSID + ": failed to set " + varName +
": " + value);
break setVariables;
}
@@ -1052,9 +1049,7 @@
if (updateFailed) {
if (newNetwork) {
WifiNative.removeNetworkCommand(netId);
- Log.d(TAG,
- "Failed to set a network variable, removed network: "
- + netId);
+ loge("Failed to set a network variable, removed network: " + netId);
}
return new NetworkUpdateResult(INVALID_NETWORK_ID);
}
@@ -1130,7 +1125,7 @@
/* Ignore */
break;
default:
- Log.e(TAG, "Ignore invalid ip assignment during write");
+ loge("Ignore invalid ip assignment during write");
break;
}
@@ -1154,7 +1149,7 @@
/* Ignore */
break;
default:
- Log.e(TAG, "Ignore invalid proxy configuration during write");
+ loge("Ignore invalid proxy configuration during write");
break;
}
@@ -1163,7 +1158,7 @@
} else {
currentConfig.ipAssignment = newConfig.ipAssignment;
addIpSettingsFromConfig(linkProperties, newConfig);
- Log.d(TAG, "IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
+ log("IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
linkProperties.toString());
}
@@ -1173,9 +1168,9 @@
} else {
currentConfig.proxySettings = newConfig.proxySettings;
linkProperties.setHttpProxy(newConfig.linkProperties.getHttpProxy());
- Log.d(TAG, "proxy changed SSID = " + currentConfig.SSID);
+ log("proxy changed SSID = " + currentConfig.SSID);
if (linkProperties.getHttpProxy() != null) {
- Log.d(TAG, " proxyProperties: " + linkProperties.getHttpProxy().toString());
+ log(" proxyProperties: " + linkProperties.getHttpProxy().toString());
}
}
@@ -1394,7 +1389,7 @@
// if we ever get here, we should probably add the
// value to WifiConfiguration to reflect that it's
// supported by the WPA supplicant
- Log.w(TAG, "Failed to look-up a string: " + string);
+ loge("Failed to look-up a string: " + string);
return -1;
}
@@ -1431,4 +1426,12 @@
public static String getConfigFile() {
return ipConfigFile;
}
+
+ private static void loge(String s) {
+ Log.e(TAG, s);
+ }
+
+ private static void log(String s) {
+ Log.d(TAG, s);
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index d1522fb..5ca7aff 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -75,7 +75,6 @@
import android.util.EventLog;
import android.util.Log;
import android.util.LruCache;
-import android.util.Slog;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.AsyncChannel;
@@ -1104,12 +1103,12 @@
mNwService.setInterfaceConfig(intf, ifcg);
}
} catch (Exception e) {
- Log.e(TAG, "Error configuring interface " + intf + ", :" + e);
+ loge("Error configuring interface " + intf + ", :" + e);
return false;
}
if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
- Log.e(TAG, "Error tethering on " + intf);
+ loge("Error tethering on " + intf);
return false;
}
return true;
@@ -1135,11 +1134,11 @@
mNwService.setInterfaceConfig(mInterfaceName, ifcg);
}
} catch (Exception e) {
- Log.e(TAG, "Error resetting interface " + mInterfaceName + ", :" + e);
+ loge("Error resetting interface " + mInterfaceName + ", :" + e);
}
if (mCm.untether(mInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
- Log.e(TAG, "Untether initiate failed!");
+ loge("Untether initiate failed!");
}
}
@@ -1175,12 +1174,12 @@
mBatteryStats.noteWifiOff();
}
} catch (RemoteException e) {
- Log.e(TAG, "Failed to note battery stats in wifi");
+ loge("Failed to note battery stats in wifi");
}
mWifiState.set(wifiState);
- if (DBG) Log.d(TAG, "setWifiState: " + syncGetWifiStateByName());
+ if (DBG) log("setWifiState: " + syncGetWifiStateByName());
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -1199,13 +1198,13 @@
mBatteryStats.noteWifiOff();
}
} catch (RemoteException e) {
- Log.d(TAG, "Failed to note battery stats in wifi");
+ loge("Failed to note battery stats in wifi");
}
// Update state
mWifiApState.set(wifiApState);
- if (DBG) Log.d(TAG, "setWifiApState: " + syncGetWifiApStateByName());
+ if (DBG) log("setWifiApState: " + syncGetWifiApStateByName());
final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -1291,7 +1290,7 @@
}
}
} else {
- Log.w(TAG, "Misformatted scan result text with " +
+ loge("Misformatted scan result text with " +
result.length + " fields: " + line);
}
}
@@ -1419,15 +1418,15 @@
private void setHighPerfModeEnabledNative(boolean enable) {
if(!WifiNative.setSuspendOptimizationsCommand(!enable)) {
- Log.e(TAG, "set suspend optimizations failed!");
+ loge("set suspend optimizations failed!");
}
if (enable) {
if (!WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE)) {
- Log.e(TAG, "set power mode active failed!");
+ loge("set power mode active failed!");
}
} else {
if (!WifiNative.setPowerModeCommand(POWER_MODE_AUTO)) {
- Log.e(TAG, "set power mode auto failed!");
+ loge("set power mode auto failed!");
}
}
}
@@ -1442,7 +1441,10 @@
mLinkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
}
mLinkProperties.setInterfaceName(mInterfaceName);
- Log.d(TAG, "netId=" + mLastNetworkId + " Link configured: " + mLinkProperties.toString());
+ if (DBG) {
+ log("netId=" + mLastNetworkId + " Link configured: " +
+ mLinkProperties.toString());
+ }
}
private int getMaxDhcpRetries() {
@@ -1503,8 +1505,11 @@
* @param state the new @{code DetailedState}
*/
private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
- Log.d(TAG, "setDetailed state, old ="
- + mNetworkInfo.getDetailedState() + " and new state=" + state);
+ if (DBG) {
+ log("setDetailed state, old ="
+ + mNetworkInfo.getDetailedState() + " and new state=" + state);
+ }
+
if (state != mNetworkInfo.getDetailedState()) {
mNetworkInfo.setDetailedState(state, null, null);
}
@@ -1547,7 +1552,7 @@
* using the interface, stopping DHCP & disabling interface
*/
private void handleNetworkDisconnect() {
- Log.d(TAG, "Stopping DHCP and clearing IP");
+ if (DBG) log("Stopping DHCP and clearing IP");
/*
* stop DHCP
@@ -1562,7 +1567,7 @@
mNwService.clearInterfaceAddresses(mInterfaceName);
mNwService.disableIpv6(mInterfaceName);
} catch (Exception e) {
- Log.e(TAG, "Failed to clear addresses or disable ipv6" + e);
+ loge("Failed to clear addresses or disable ipv6" + e);
}
/* Reset data structures */
@@ -1647,8 +1652,10 @@
linkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
linkProperties.setInterfaceName(mInterfaceName);
if (!linkProperties.equals(mLinkProperties)) {
- Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId
- + " old: " + mLinkProperties + "new: " + linkProperties);
+ if (DBG) {
+ log("Link configuration changed for netId: " + mLastNetworkId
+ + " old: " + mLinkProperties + "new: " + linkProperties);
+ }
mLinkProperties = linkProperties;
sendLinkConfigurationChangedBroadcast();
}
@@ -1660,7 +1667,7 @@
}
private void handleFailedIpConfiguration() {
- Log.e(TAG, "IP configuration failed");
+ loge("IP configuration failed");
mWifiInfo.setInetAddress(null);
/**
@@ -1668,7 +1675,7 @@
* to a given network, disable the network
*/
if (++mReconnectCount > getMaxDhcpRetries()) {
- Log.e(TAG, "Failed " +
+ loge("Failed " +
mReconnectCount + " times, Disabling " + mLastNetworkId);
WifiConfigStore.disableNetwork(mLastNetworkId,
WifiConfiguration.DISABLED_DHCP_FAILURE);
@@ -1697,12 +1704,12 @@
try {
mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
} catch (Exception e) {
- Log.e(TAG, "Exception in softap start " + e);
+ loge("Exception in softap start " + e);
try {
mNwService.stopAccessPoint(mInterfaceName);
mNwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
} catch (Exception e1) {
- Log.e(TAG, "Exception in softap re-start " + e1);
+ loge("Exception in softap re-start " + e1);
return false;
}
}
@@ -1716,17 +1723,17 @@
class DefaultState extends State {
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
} else {
- Log.e(TAG, "WifiP2pService connection failure, error=" + message.arg1);
+ loge("WifiP2pService connection failure, error=" + message.arg1);
}
break;
case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- Log.e(TAG, "WifiP2pService channel lost, message.arg1 =" + message.arg1);
+ loge("WifiP2pService channel lost, message.arg1 =" + message.arg1);
//TODO: Re-establish connection to state machine after a delay
//mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
break;
@@ -1812,7 +1819,7 @@
deferMessage(message);
break;
default:
- Log.e(TAG, "Error! unhandled message" + message);
+ loge("Error! unhandled message" + message);
break;
}
return HANDLED;
@@ -1823,7 +1830,7 @@
@Override
//TODO: could move logging into a common class
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
// [31-8] Reserved for future use
// [7 - 0] HSM state change
// 50021 wifi_state_changed (custom|1|5)
@@ -1853,9 +1860,9 @@
try {
mNwService.disableIpv6(mInterfaceName);
} catch (RemoteException re) {
- Log.e(TAG, "Failed to disable IPv6: " + re);
+ loge("Failed to disable IPv6: " + re);
} catch (IllegalStateException e) {
- Log.e(TAG, "Failed to disable IPv6: " + e);
+ loge("Failed to disable IPv6: " + e);
}
}
}
@@ -1863,7 +1870,7 @@
class DriverLoadingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
final Message message = new Message();
@@ -1885,10 +1892,10 @@
}
if(WifiNative.loadDriver()) {
- Log.d(TAG, "Driver load successful");
+ if (DBG) log("Driver load successful");
sendMessage(CMD_LOAD_DRIVER_SUCCESS);
} else {
- Log.e(TAG, "Failed to load driver!");
+ loge("Failed to load driver!");
switch(message.arg1) {
case WIFI_STATE_ENABLING:
setWifiState(WIFI_STATE_UNKNOWN);
@@ -1906,7 +1913,7 @@
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_LOAD_DRIVER_SUCCESS:
transitionTo(mDriverLoadedState);
@@ -1942,12 +1949,12 @@
class DriverLoadedState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case CMD_UNLOAD_DRIVER:
transitionTo(mDriverUnloadingState);
@@ -1956,7 +1963,7 @@
try {
mNwService.wifiFirmwareReload(mInterfaceName, "STA");
} catch (Exception e) {
- Log.e(TAG, "Failed to reload STA firmware " + e);
+ loge("Failed to reload STA firmware " + e);
// continue
}
try {
@@ -1967,17 +1974,17 @@
//Set privacy extensions
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
} catch (RemoteException re) {
- if (DBG) Log.w(TAG, "Unable to change interface settings: " + re);
+ loge("Unable to change interface settings: " + re);
} catch (IllegalStateException ie) {
- if (DBG) Log.w(TAG, "Unable to change interface settings: " + ie);
+ loge("Unable to change interface settings: " + ie);
}
if(WifiNative.startSupplicant()) {
- Log.d(TAG, "Supplicant start successful");
+ if (DBG) log("Supplicant start successful");
mWifiMonitor.startMonitoring();
transitionTo(mSupplicantStartingState);
} else {
- Log.e(TAG, "Failed to start supplicant!");
+ loge("Failed to start supplicant!");
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
}
break;
@@ -1995,17 +2002,17 @@
class DriverUnloadingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
final Message message = new Message();
message.copyFrom(getCurrentMessage());
new Thread(new Runnable() {
public void run() {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
mWakeLock.acquire();
if(WifiNative.unloadDriver()) {
- Log.d(TAG, "Driver unload successful");
+ if (DBG) log("Driver unload successful");
sendMessage(CMD_UNLOAD_DRIVER_SUCCESS);
switch(message.arg1) {
@@ -2019,7 +2026,7 @@
break;
}
} else {
- Log.e(TAG, "Failed to unload driver!");
+ loge("Failed to unload driver!");
sendMessage(CMD_UNLOAD_DRIVER_FAILURE);
switch(message.arg1) {
@@ -2040,7 +2047,7 @@
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_UNLOAD_DRIVER_SUCCESS:
transitionTo(mDriverUnloadedState);
@@ -2076,12 +2083,12 @@
class DriverUnloadedState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_LOAD_DRIVER:
mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);
@@ -2101,12 +2108,12 @@
class DriverFailedState extends State {
@Override
public void enter() {
- Log.e(TAG, getName() + "\n");
+ loge(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
return NOT_HANDLED;
}
}
@@ -2115,15 +2122,15 @@
class SupplicantStartingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case WifiMonitor.SUP_CONNECTION_EVENT:
- Log.d(TAG, "Supplicant connection established");
+ if (DBG) log("Supplicant connection established");
setWifiState(WIFI_STATE_ENABLED);
mSupplicantRestartCount = 0;
/* Reset the supplicant state to indicate the supplicant
@@ -2144,12 +2151,12 @@
break;
case WifiMonitor.SUP_DISCONNECTION_EVENT:
if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
- Log.e(TAG, "Failed to setup control channel, restart supplicant");
+ loge("Failed to setup control channel, restart supplicant");
WifiNative.killSupplicant();
transitionTo(mDriverLoadedState);
sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
} else {
- Log.e(TAG, "Failed " + mSupplicantRestartCount +
+ loge("Failed " + mSupplicantRestartCount +
" times to start supplicant, unload driver");
mSupplicantRestartCount = 0;
transitionTo(mDriverLoadedState);
@@ -2184,7 +2191,7 @@
class SupplicantStartedState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
/* Initialize for connect mode operation at start */
mIsScanMode = false;
@@ -2198,7 +2205,7 @@
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
WifiConfiguration config;
boolean eventLoggingEnabled = true;
switch(message.what) {
@@ -2206,7 +2213,7 @@
transitionTo(mSupplicantStoppingState);
break;
case WifiMonitor.SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */
- Log.e(TAG, "Connection lost, restart supplicant");
+ loge("Connection lost, restart supplicant");
WifiNative.killSupplicant();
WifiNative.closeSupplicantConnection();
mNetworkInfo.setIsAvailable(false);
@@ -2270,7 +2277,7 @@
break;
/* Cannot start soft AP while in client mode */
case CMD_START_AP:
- Log.d(TAG, "Failed to start soft AP with a running supplicant");
+ loge("Failed to start soft AP with a running supplicant");
setWifiApState(WIFI_AP_STATE_FAILED);
break;
case CMD_SET_SCAN_MODE:
@@ -2301,11 +2308,11 @@
class SupplicantStoppingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
- Log.d(TAG, "stopping supplicant");
+ if (DBG) log("stopping supplicant");
if (!WifiNative.stopSupplicant()) {
- Log.e(TAG, "Failed to stop supplicant");
+ loge("Failed to stop supplicant");
}
/* Send ourselves a delayed message to indicate failure after a wait time */
@@ -2321,13 +2328,13 @@
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case WifiMonitor.SUP_CONNECTION_EVENT:
- Log.e(TAG, "Supplicant connection received while stopping");
+ loge("Supplicant connection received while stopping");
break;
case WifiMonitor.SUP_DISCONNECTION_EVENT:
- Log.d(TAG, "Supplicant connection lost");
+ if (DBG) log("Supplicant connection lost");
/* Socket connection can be lost when we do a graceful shutdown
* or when the driver is hung. Ensure supplicant is stopped here.
*/
@@ -2337,7 +2344,7 @@
break;
case CMD_STOP_SUPPLICANT_FAILED:
if (message.arg1 == mSupplicantStopFailureToken) {
- Log.e(TAG, "Timed out on a supplicant stop, kill and proceed");
+ loge("Timed out on a supplicant stop, kill and proceed");
WifiNative.killSupplicant();
WifiNative.closeSupplicantConnection();
transitionTo(mDriverLoadedState);
@@ -2371,12 +2378,12 @@
class DriverStartingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
SupplicantState state = handleSupplicantStateChange(message);
@@ -2418,7 +2425,7 @@
class DriverStartedState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
mIsRunning = true;
@@ -2459,7 +2466,7 @@
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
boolean eventLoggingEnabled = true;
switch(message.what) {
case CMD_SET_SCAN_TYPE:
@@ -2479,20 +2486,20 @@
break;
case CMD_SET_COUNTRY_CODE:
String country = (String) message.obj;
- Log.d(TAG, "set country code " + country);
+ if (DBG) log("set country code " + country);
if (!WifiNative.setCountryCodeCommand(country.toUpperCase())) {
- Log.e(TAG, "Failed to set country code " + country);
+ loge("Failed to set country code " + country);
}
break;
case CMD_SET_FREQUENCY_BAND:
int band = message.arg1;
- Log.d(TAG, "set frequency band " + band);
+ if (DBG) log("set frequency band " + band);
if (WifiNative.setBandCommand(band)) {
mFrequencyBand.set(band);
//Fetch the latest scan results when frequency band is set
startScan(true);
} else {
- Log.e(TAG, "Failed to set frequency band " + band);
+ loge("Failed to set frequency band " + band);
}
break;
case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
@@ -2512,7 +2519,7 @@
} else if (message.arg1 == MULTICAST_V4) {
WifiNative.startFilteringMulticastV4Packets();
} else {
- Log.e(TAG, "Illegal arugments to CMD_START_PACKET_FILTERING");
+ loge("Illegal arugments to CMD_START_PACKET_FILTERING");
}
break;
case CMD_STOP_PACKET_FILTERING:
@@ -2521,7 +2528,7 @@
} else if (message.arg1 == MULTICAST_V4) {
WifiNative.stopFilteringMulticastV4Packets();
} else {
- Log.e(TAG, "Illegal arugments to CMD_STOP_PACKET_FILTERING");
+ loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
}
break;
default:
@@ -2534,7 +2541,7 @@
}
@Override
public void exit() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
mIsRunning = false;
updateBatteryWorkSource(null);
mScanResults = null;
@@ -2544,12 +2551,12 @@
class DriverStoppingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
SupplicantState state = handleSupplicantStateChange(message);
@@ -2583,12 +2590,12 @@
class DriverStoppedState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_START_DRIVER:
mWakeLock.acquire();
@@ -2607,12 +2614,12 @@
class ScanModeState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case CMD_SET_SCAN_MODE:
if (message.arg1 == SCAN_ONLY_MODE) {
@@ -2644,12 +2651,12 @@
class ConnectModeState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
StateChangeResult stateChangeResult;
switch(message.what) {
case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
@@ -2696,7 +2703,7 @@
mLastExplicitNetworkId = netId;
mLastNetworkChoiceTime = SystemClock.elapsedRealtime();
mNextWifiActionExplicit = true;
- Slog.d(TAG, "Setting wifi connect explicit for netid " + netId);
+ if (DBG) log("Setting wifi connect explicit for netid " + netId);
/* Expect a disconnection from the old connection */
transitionTo(mDisconnectingState);
break;
@@ -2710,7 +2717,7 @@
/* Handle scan results */
return NOT_HANDLED;
case WifiMonitor.NETWORK_CONNECTION_EVENT:
- Log.d(TAG,"Network connection established");
+ if (DBG) log("Network connection established");
mLastNetworkId = message.arg1;
mLastBssid = (String) message.obj;
@@ -2731,7 +2738,7 @@
transitionTo(mConnectingState);
break;
case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
- Log.d(TAG,"Network connection lost");
+ if (DBG) log("Network connection lost");
handleNetworkDisconnect();
transitionTo(mDisconnectedState);
break;
@@ -2747,15 +2754,15 @@
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
try {
mNwService.enableIpv6(mInterfaceName);
} catch (RemoteException re) {
- Log.e(TAG, "Failed to enable IPv6: " + re);
+ loge("Failed to enable IPv6: " + re);
} catch (IllegalStateException e) {
- Log.e(TAG, "Failed to enable IPv6: " + e);
+ loge("Failed to enable IPv6: " + e);
}
if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
@@ -2772,20 +2779,20 @@
ifcg.interfaceFlags = "[up]";
try {
mNwService.setInterfaceConfig(mInterfaceName, ifcg);
- Log.v(TAG, "Static IP configuration succeeded");
+ if (DBG) log("Static IP configuration succeeded");
sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
} catch (RemoteException re) {
- Log.v(TAG, "Static IP configuration failed: " + re);
+ loge("Static IP configuration failed: " + re);
sendMessage(CMD_STATIC_IP_FAILURE);
} catch (IllegalStateException e) {
- Log.v(TAG, "Static IP configuration failed: " + e);
+ loge("Static IP configuration failed: " + e);
sendMessage(CMD_STATIC_IP_FAILURE);
}
}
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
@@ -2856,7 +2863,7 @@
class ConnectedState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
mRssiPollToken++;
if (mEnableRssiPolling) {
@@ -2865,7 +2872,7 @@
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
boolean eventLoggingEnabled = true;
switch (message.what) {
case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
@@ -2921,11 +2928,11 @@
NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
if (result.hasIpChanged()) {
- Log.d(TAG,"Reconfiguring IP on connection");
+ log("Reconfiguring IP on connection");
transitionTo(mConnectingState);
}
if (result.hasProxyChanged()) {
- Log.d(TAG,"Reconfiguring proxy on connection");
+ log("Reconfiguring proxy on connection");
configureLinkProperties();
sendLinkConfigurationChangedBroadcast();
}
@@ -2977,12 +2984,12 @@
class DisconnectingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_STOP_DRIVER: /* Stop driver only after disconnect handled */
deferMessage(message);
@@ -3029,7 +3036,7 @@
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
mFrameworkScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(),
@@ -3056,7 +3063,7 @@
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_SET_SCAN_MODE:
if (message.arg1 == SCAN_ONLY_MODE) {
@@ -3119,12 +3126,12 @@
class WaitForWpsCompletionState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
/* Defer all commands that can cause connections to a different network
* or put the state machine out of connect mode
@@ -3139,7 +3146,7 @@
deferMessage(message);
break;
case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
- Log.d(TAG,"Network connection lost");
+ if (DBG) log("Network connection lost");
handleNetworkDisconnect();
break;
case WPS_COMPLETED_EVENT:
@@ -3158,7 +3165,7 @@
class SoftApStartingState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
final Message message = Message.obtain(getCurrentMessage());
@@ -3168,10 +3175,10 @@
new Thread(new Runnable() {
public void run() {
if (startSoftApWithConfig(config)) {
- Log.d(TAG, "Soft AP start successful");
+ if (DBG) log("Soft AP start successful");
sendMessage(CMD_START_AP_SUCCESS);
} else {
- Log.d(TAG, "Soft AP start failed");
+ loge("Soft AP start failed");
sendMessage(CMD_START_AP_FAILURE);
}
}
@@ -3179,7 +3186,7 @@
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case CMD_LOAD_DRIVER:
case CMD_UNLOAD_DRIVER:
@@ -3219,21 +3226,21 @@
class SoftApStartedState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case CMD_STOP_AP:
- Log.d(TAG,"Stopping Soft AP");
+ if (DBG) log("Stopping Soft AP");
setWifiApState(WIFI_AP_STATE_DISABLING);
stopTethering();
try {
mNwService.stopAccessPoint(mInterfaceName);
} catch(Exception e) {
- Log.e(TAG, "Exception in stopAccessPoint()");
+ loge("Exception in stopAccessPoint()");
}
transitionTo(mDriverLoadedState);
break;
@@ -3242,7 +3249,7 @@
break;
/* Fail client mode operation when soft AP is enabled */
case CMD_START_SUPPLICANT:
- Log.e(TAG,"Cannot start supplicant with a running soft AP");
+ loge("Cannot start supplicant with a running soft AP");
setWifiState(WIFI_STATE_UNKNOWN);
break;
case CMD_TETHER_INTERFACE:
@@ -3268,7 +3275,7 @@
private int mSavedArg;
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
//Preserve the argument arg1 that has information used in DriverLoadingState
@@ -3276,7 +3283,7 @@
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case WifiP2pService.WIFI_ENABLE_PROCEED:
//restore argument from original message (CMD_LOAD_DRIVER)
@@ -3311,12 +3318,12 @@
class TetheredState extends State {
@Override
public void enter() {
- if (DBG) Log.d(TAG, getName() + "\n");
+ if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
- if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ if (DBG) log(getName() + message.toString() + "\n");
switch(message.what) {
case CMD_TETHER_INTERFACE:
// Ignore any duplicate interface available notifications
@@ -3327,4 +3334,12 @@
}
}
}
+
+ private void log(String s) {
+ Log.d(TAG, s);
+ }
+
+ private void loge(String s) {
+ Log.e(TAG, s);
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index af8c486..5d5b9ef 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -35,7 +35,6 @@
import android.os.SystemProperties;
import android.provider.Settings;
import android.provider.Settings.Secure;
-import android.util.Slog;
import android.util.Log;
import com.android.internal.util.Protocol;
@@ -67,10 +66,8 @@
*/
public class WifiWatchdogStateMachine extends StateMachine {
-
- private static final boolean VDBG = false;
- private static final boolean DBG = true;
- private static final String WWSM_TAG = "WifiWatchdogStateMachine";
+ private static final boolean DBG = false;
+ private static final String TAG = "WifiWatchdogStateMachine";
private static final String WATCHDOG_NOTIFICATION_ID = "Android.System.WifiWatchdog";
private static final int WIFI_SIGNAL_LEVELS = 4;
@@ -192,7 +189,7 @@
* (all other states)
*/
private WifiWatchdogStateMachine(Context context) {
- super(WWSM_TAG);
+ super(TAG);
mContext = context;
mContentResolver = context.getContentResolver();
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
@@ -351,7 +348,7 @@
return urlConnection.getResponseCode() != 204;
} catch (IOException e) {
if (DBG) {
- Slog.d(WWSM_TAG, "Walled garden check - probably not a portal: exception ", e);
+ log("Walled garden check - probably not a portal: exception " + e);
}
return false;
} finally {
@@ -443,7 +440,7 @@
if (results == null) {
if (DBG) {
- Slog.d(WWSM_TAG, "updateBssids: Got null scan results!");
+ log("updateBssids: Got null scan results!");
}
return;
}
@@ -451,7 +448,7 @@
for (ScanResult result : results) {
if (result == null || result.SSID == null) {
if (DBG) {
- Slog.d(WWSM_TAG, "Received invalid scan result: " + result);
+ log("Received invalid scan result: " + result);
}
continue;
}
@@ -461,8 +458,8 @@
}
private void resetWatchdogState() {
- if (VDBG) {
- Slog.v(WWSM_TAG, "Resetting watchdog state...");
+ if (DBG) {
+ log("Resetting watchdog state...");
}
mConnectionInfo = null;
mDisableAPNextFailure = false;
@@ -522,13 +519,13 @@
switch (msg.what) {
case EVENT_WATCHDOG_SETTINGS_CHANGE:
updateSettings();
- if (VDBG) {
- Slog.d(WWSM_TAG, "Updating wifi-watchdog secure settings");
+ if (DBG) {
+ log("Updating wifi-watchdog secure settings");
}
return HANDLED;
}
- if (VDBG) {
- Slog.v(WWSM_TAG, "Caught message " + msg.what + " in state " +
+ if (DBG) {
+ log("Caught message " + msg.what + " in state " +
getCurrentState().getName());
}
return HANDLED;
@@ -553,7 +550,7 @@
public void enter() {
resetWatchdogState();
mContext.registerReceiver(mBroadcastReceiver, mIntentFilter);
- Slog.i(WWSM_TAG, "WifiWatchdogService enabled");
+ if (DBG) log("WifiWatchdogService enabled");
}
@Override
@@ -574,12 +571,12 @@
WifiInfo wifiInfo = (WifiInfo)
stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
if (wifiInfo == null) {
- Slog.e(WWSM_TAG, "Connected --> WifiInfo object null!");
+ loge("Connected --> WifiInfo object null!");
return HANDLED;
}
if (wifiInfo.getSSID() == null || wifiInfo.getBSSID() == null) {
- Slog.e(WWSM_TAG, "Received wifiInfo object with null elts: "
+ loge("Received wifiInfo object with null elts: "
+ wifiInfoToStr(wifiInfo));
return HANDLED;
}
@@ -598,7 +595,7 @@
return HANDLED;
case EVENT_WIFI_RADIO_STATE_CHANGE:
if ((Integer) msg.obj == WifiManager.WIFI_STATE_DISABLING) {
- Slog.i(WWSM_TAG, "WifiStateDisabling -- Resetting WatchdogState");
+ if (DBG) log("WifiStateDisabling -- Resetting WatchdogState");
resetWatchdogState();
mNetEventCounter++;
transitionTo(mNotConnectedState);
@@ -613,8 +610,8 @@
* @param wifiInfo Info object with non-null ssid and bssid
*/
private void initConnection(WifiInfo wifiInfo) {
- if (VDBG) {
- Slog.v(WWSM_TAG, "Connected:: old " + wifiInfoToStr(mConnectionInfo) +
+ if (DBG) {
+ log("Connected:: old " + wifiInfoToStr(mConnectionInfo) +
" ==> new " + wifiInfoToStr(wifiInfo));
}
@@ -628,7 +625,7 @@
@Override
public void exit() {
mContext.unregisterReceiver(mBroadcastReceiver);
- Slog.i(WWSM_TAG, "WifiWatchdogService disabled");
+ if (DBG) log("WifiWatchdogService disabled");
}
}
@@ -671,7 +668,7 @@
if (DBG) {
dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ",
mDnsList, mConnectionInfo.getSSID());
- Slog.d(WWSM_TAG, dnsCheckLogStr);
+ log(dnsCheckLogStr);
}
idDnsMap.clear();
@@ -694,7 +691,7 @@
Integer dnsServerId = idDnsMap.get(pingID);
if (dnsServerId == null) {
- Slog.w(WWSM_TAG, "Received a Dns response with unknown ID!");
+ loge("Received a Dns response with unknown ID!");
return HANDLED;
}
@@ -722,7 +719,7 @@
if (dnsCheckSuccesses[dnsServerId] >= mMinDnsResponses) {
// DNS CHECKS OK, NOW WALLED GARDEN
if (DBG) {
- Slog.d(WWSM_TAG, makeLogString() + " SUCCESS");
+ log(makeLogString() + " SUCCESS");
}
if (!shouldCheckWalledGarden()) {
@@ -732,13 +729,10 @@
mLastWalledGardenCheckTime = SystemClock.elapsedRealtime();
if (isWalledGardenConnection()) {
- if (DBG)
- Slog.d(WWSM_TAG,
- "Walled garden test complete - walled garden detected");
+ if (DBG) log("Walled garden test complete - walled garden detected");
transitionTo(mWalledGardenState);
} else {
- if (DBG)
- Slog.d(WWSM_TAG, "Walled garden test complete - online");
+ if (DBG) log("Walled garden test complete - online");
transitionTo(mOnlineWatchState);
}
return HANDLED;
@@ -746,7 +740,7 @@
if (idDnsMap.isEmpty()) {
if (DBG) {
- Slog.d(WWSM_TAG, makeLogString() + " FAILURE");
+ log(makeLogString() + " FAILURE");
}
transitionTo(mDnsCheckFailureState);
return HANDLED;
@@ -769,15 +763,15 @@
private boolean shouldCheckWalledGarden() {
if (!mWalledGardenTestEnabled) {
- if (VDBG)
- Slog.v(WWSM_TAG, "Skipping walled garden check - disabled");
+ if (DBG)
+ log("Skipping walled garden check - disabled");
return false;
}
long waitTime = waitTime(mWalledGardenIntervalMs,
mLastWalledGardenCheckTime);
if (waitTime > 0) {
if (DBG) {
- Slog.d(WWSM_TAG, "Skipping walled garden check - wait " +
+ log("Skipping walled garden check - wait " +
waitTime + " ms.");
}
return false;
@@ -825,28 +819,28 @@
case EVENT_RSSI_CHANGE:
if (msg.arg1 != mNetEventCounter) {
if (DBG) {
- Slog.d(WWSM_TAG, "Rssi change message out of sync, ignoring");
+ log("Rssi change message out of sync, ignoring");
}
return HANDLED;
}
int newRssi = msg.arg2;
signalUnstable = !rssiStrengthAboveCutoff(newRssi);
- if (VDBG) {
- Slog.v(WWSM_TAG, "OnlineWatchState:: new rssi " + newRssi + " --> level " +
+ if (DBG) {
+ log("OnlineWatchState:: new rssi " + newRssi + " --> level " +
WifiManager.calculateSignalLevel(newRssi, WIFI_SIGNAL_LEVELS));
}
if (signalUnstable && !unstableSignalChecks) {
- if (VDBG) {
- Slog.v(WWSM_TAG, "Sending triggered check msg");
+ if (DBG) {
+ log("Sending triggered check msg");
}
triggerSingleDnsCheck();
}
return HANDLED;
case MESSAGE_SINGLE_DNS_CHECK:
if (msg.arg1 != checkGuard) {
- if (VDBG) {
- Slog.v(WWSM_TAG, "Single check msg out of sync, ignoring.");
+ if (DBG) {
+ log("Single check msg out of sync, ignoring.");
}
return HANDLED;
}
@@ -865,8 +859,8 @@
pingInfoMap.remove(msg.arg1);
int responseTime = msg.arg2;
if (responseTime >= 0) {
- if (VDBG) {
- Slog.v(WWSM_TAG, "Single DNS ping OK. Response time: "
+ if (DBG) {
+ log("Single DNS ping OK. Response time: "
+ responseTime + " from DNS " + curDnsServer);
}
pingInfoMap.clear();
@@ -877,7 +871,7 @@
} else {
if (pingInfoMap.isEmpty()) {
if (DBG) {
- Slog.d(WWSM_TAG, "Single dns ping failure. All dns servers failed, "
+ log("Single dns ping failure. All dns servers failed, "
+ "starting full checks.");
}
transitionTo(mDnsCheckingState);
@@ -924,8 +918,8 @@
}
if (msg.arg1 != mNetEventCounter) {
- if (VDBG) {
- Slog.v(WWSM_TAG, "Msg out of sync, ignoring...");
+ if (DBG) {
+ log("Msg out of sync, ignoring...");
}
return HANDLED;
}
@@ -933,7 +927,7 @@
if (mDisableAPNextFailure || mNumCheckFailures >= mBssids.size()
|| mNumCheckFailures >= mMaxSsidBlacklists) {
if (sWifiOnly) {
- Slog.w(WWSM_TAG, "Would disable bad network, but device has no mobile data!" +
+ log("Would disable bad network, but device has no mobile data!" +
" Going idle...");
// This state should be called idle -- will be changing flow.
transitionTo(mNotConnectedState);
@@ -941,7 +935,7 @@
}
// TODO : Unban networks if they had low signal ?
- Slog.i(WWSM_TAG, "Disabling current SSID " + wifiInfoToStr(mConnectionInfo)
+ log("Disabling current SSID " + wifiInfoToStr(mConnectionInfo)
+ ". " + "numCheckFailures " + mNumCheckFailures
+ ", numAPs " + mBssids.size());
int networkId = mConnectionInfo.getNetworkId();
@@ -955,7 +949,7 @@
}
transitionTo(mNotConnectedState);
} else {
- Slog.i(WWSM_TAG, "Blacklisting current BSSID. " + wifiInfoToStr(mConnectionInfo)
+ log("Blacklisting current BSSID. " + wifiInfoToStr(mConnectionInfo)
+ "numCheckFailures " + mNumCheckFailures + ", numAPs " + mBssids.size());
mWifiManager.addToBlacklist(mConnectionInfo.getBSSID());
@@ -979,8 +973,8 @@
}
if (msg.arg1 != mNetEventCounter) {
- if (VDBG) {
- Slog.v(WWSM_TAG, "WalledGardenState::Msg out of sync, ignoring...");
+ if (DBG) {
+ log("WalledGardenState::Msg out of sync, ignoring...");
}
return HANDLED;
}
@@ -1005,8 +999,8 @@
}
if (msg.arg1 != mNetEventCounter) {
- if (VDBG) {
- Slog.v(WWSM_TAG, "BlacklistedApState::Msg out of sync, ignoring...");
+ if (DBG) {
+ log("BlacklistedApState::Msg out of sync, ignoring...");
}
return HANDLED;
}
@@ -1067,5 +1061,11 @@
return Settings.Secure.putInt(cr, name, value ? 1 : 0);
}
+ private void log(String s) {
+ Log.d(TAG, s);
+ }
+ private void loge(String s) {
+ Log.e(TAG, s);
+ }
}