diff options
88 files changed, 1385 insertions, 650 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index eb8471a74831..1c8527916651 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -114,6 +114,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/) $(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 034e3c787766..4a144a2355b4 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -3246,6 +3246,7 @@ public class Activity extends ContextThemeWrapper try { String resolvedType = null; if (fillInIntent != null) { + fillInIntent.setAllowFds(false); resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); } int result = ActivityManagerNative.getDefault() @@ -3370,6 +3371,7 @@ public class Activity extends ContextThemeWrapper 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 class Activity extends ContextThemeWrapper 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 @@ public class Activity extends ContextThemeWrapper } 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 @@ public class Activity extends ContextThemeWrapper 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 0776e1015c3c..99aae37ff73d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2674,6 +2674,7 @@ public final class ActivityThread { // 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 @@ public final class ActivityThread { 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 @@ public final class ActivityThread { } 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 21397040357f..2bf1fb712304 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -874,6 +874,7 @@ class ContextImpl extends Context { try { String resolvedType = null; if (fillInIntent != null) { + fillInIntent.setAllowFds(false); resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); } int result = ActivityManagerNative.getDefault() @@ -892,6 +893,7 @@ class ContextImpl extends Context { 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 @@ class ContextImpl extends Context { 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 @@ class ContextImpl extends Context { 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 @@ class ContextImpl extends Context { } 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 @@ class ContextImpl extends Context { 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 @@ class ContextImpl extends Context { } 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 @@ class ContextImpl extends Context { intent.setDataAndType(intent.getData(), resolvedType); } try { + intent.setAllowFds(false); ActivityManagerNative.getDefault().unbroadcastIntent( mMainThread.getApplicationThread(), intent); } catch (RemoteException e) { @@ -1069,6 +1077,7 @@ class ContextImpl extends Context { @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 @@ class ContextImpl extends Context { @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 @@ class ContextImpl extends Context { < 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 @@ class ContextImpl extends Context { 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 f3bc495e2a91..d7f5c55e4c68 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1375,6 +1375,7 @@ public class Instrumentation { } } try { + intent.setAllowFds(false); int result = ActivityManagerNative.getDefault() .startActivity(whoThread, intent, intent.resolveTypeIfNeeded(who.getContentResolver()), @@ -1415,6 +1416,7 @@ public class Instrumentation { 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 @@ public class Instrumentation { } } 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 2549c84a9f95..522f47760a49 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -661,6 +661,9 @@ public final class LoadedApk { "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 b4827cbb7a65..b0637a716f9b 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -192,6 +192,7 @@ public final class PendingIntent implements Parcelable { 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 @@ public final class PendingIntent implements Parcelable { 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 @@ public final class PendingIntent implements Parcelable { 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 @@ public final class PendingIntent implements Parcelable { 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 028149b3760b..3cbaf929e549 100644 --- a/core/java/android/content/BroadcastReceiver.java +++ b/core/java/android/content/BroadcastReceiver.java @@ -366,6 +366,9 @@ public abstract class BroadcastReceiver { mFinished = true; try { + if (mResultExtras != null) { + mResultExtras.setAllowFds(false); + } if (mOrderedHint) { am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras, mAbortBroadcast); @@ -462,6 +465,7 @@ public abstract class BroadcastReceiver { 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 f44d038a5fee..08fe0aae74e2 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3568,6 +3568,13 @@ public class Intent implements Parcelable, Cloneable { 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 127efa219308..42253930ae98 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -1301,7 +1301,7 @@ public class SyncManager implements OnAccountsUpdateListener { 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 @@ public class SyncManager implements OnAccountsUpdateListener { 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 @@ public class SyncManager implements OnAccountsUpdateListener { 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 @@ public class SyncManager implements OnAccountsUpdateListener { final long eventTime = item.eventTime; time.set(eventTime); - pw.printf(" #%-3d: %s %8s %5.1fs", - 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); + final String key = authorityName + "/" + accountKey; + final Long lastEventTime = lastTimeMap.get(key); + final String diffString; + if (lastEventTime == null) { + diffString = ""; } else { - pw.printf(format, accountKey, authorityName); + 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); - lastAuthorityName = authorityName; - lastAccountKey = accountKey; - lastEventTime = eventTime; + pw.printf(" #%-3d: %s %8s %5.1fs %8s", + i + 1, + formatTime(eventTime), + SyncStorageEngine.SOURCES[item.source], + ((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 79c939565804..fc6a44a3799b 100644 --- a/core/java/android/net/DhcpStateMachine.java +++ b/core/java/android/net/DhcpStateMachine.java @@ -336,17 +336,17 @@ public class DhcpStateMachine extends StateMachine { 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 @@ public class DhcpStateMachine extends StateMachine { 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 3291e6b5c917..11acabebf434 100644 --- a/core/java/android/net/DnsPinger.java +++ b/core/java/android/net/DnsPinger.java @@ -22,7 +22,7 @@ import android.os.Looper; 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 @@ import java.util.concurrent.atomic.AtomicInteger; * @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 @@ public final class DnsPinger extends Handler { 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 @@ public final class DnsPinger extends Handler { // 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 @@ public final class DnsPinger extends Handler { 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 final class DnsPinger extends Handler { 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 @@ public final class DnsPinger extends Handler { } 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 @@ public final class DnsPinger extends Handler { 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 @@ public final class DnsPinger extends Handler { 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 c288f8a21b23..28206b77e093 100644 --- a/core/java/android/os/Bundle.java +++ b/core/java/android/os/Bundle.java @@ -54,6 +54,7 @@ public final class Bundle implements Parcelable, Cloneable { 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 final class Bundle implements Parcelable, Cloneable { 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 @@ public final class Bundle implements Parcelable, Cloneable { * @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 e9ed67650ca4..15e3af42c4e3 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -323,6 +323,12 @@ public final class Parcel { */ 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 886edaf9f46b..6d14dfc7ad4a 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -238,6 +238,14 @@ public class CallLog { 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 d26364ec7159..da7c489960a4 100644 --- a/core/java/android/server/BluetoothAdapterStateMachine.java +++ b/core/java/android/server/BluetoothAdapterStateMachine.java @@ -77,6 +77,12 @@ final class BluetoothAdapterStateMachine extends StateMachine { 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 @@ final class BluetoothAdapterStateMachine extends StateMachine { // 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 @@ final class BluetoothAdapterStateMachine extends StateMachine { 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 63da9268fd01..9ca58477dd41 100755 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -313,6 +313,10 @@ public class BluetoothService extends IBluetooth.Stub { 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 e9549834b215..34e7d4d746bb 100644 --- a/core/java/android/view/ActionMode.java +++ b/core/java/android/view/ActionMode.java @@ -153,6 +153,18 @@ public abstract class ActionMode { 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 d193d6e41504..9628afbcb11f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1487,6 +1487,18 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } /** + * 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 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal 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 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * {@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 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * 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 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal } /** + * 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 fb0d80a688e4..5b4a6f8a78e6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -821,6 +821,24 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + @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 9cb4e5e7b0a8..e7c91f983bf2 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -74,7 +74,6 @@ import android.view.inputmethod.InputMethodManager; 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 @@ public final class ViewRootImpl extends Handler implements ViewParent, 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 @@ public final class ViewRootImpl extends Handler implements ViewParent, 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 @@ public final class ViewRootImpl extends Handler implements ViewParent, 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 final class ViewRootImpl extends Handler implements ViewParent, 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 c93b5648aa38..91fbb0e2d66d 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -69,14 +69,16 @@ import java.util.List; * <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 @@ import java.util.List; * <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 @@ import java.util.List; * <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 @@ import java.util.List; * <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 @@ import java.util.List; * <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 @@ import java.util.List; * <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 @@ import java.util.List; * <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 @@ import java.util.List; * (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 @@ import java.util.List; * 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 a322fa3d160d..739826243174 100644 --- a/core/java/android/webkit/FindActionModeCallback.java +++ b/core/java/android/webkit/FindActionModeCallback.java @@ -180,6 +180,14 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, @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 104deb1c82f0..8c174aa8a796 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 @@ class SelectActionModeCallback implements ActionMode.Callback { @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 851c70626cb3..eaed9fecc4fa 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -4078,8 +4078,8 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout .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 @@ public class WebView extends AbsoluteLayout mDrawCursorRing = true; setFocusControllerActive(true); if (mNativeClass != 0) { - nativeRecordButtons(true, false, true); + recordButtons(null, true, false, true); } } else { if (!inEditingMode()) { @@ -5570,7 +5570,7 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout if (!inEditingMode()) { mDrawCursorRing = false; if (mNativeClass != 0) { - nativeRecordButtons(false, false, true); + recordButtons(null, false, false, true); } setFocusControllerActive(false); } @@ -6762,7 +6762,7 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 a4b4e783def9..61c5dd43e9cd 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -881,20 +881,14 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { @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 84ebec34e3d1..63a0870307f7 100644 --- a/core/java/android/widget/AnalogClock.java +++ b/core/java/android/widget/AnalogClock.java @@ -25,6 +25,7 @@ import android.content.res.TypedArray; 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 @@ public class AnalogClock extends View { mMinutes = minute + second / 60.0f; mHour = hour + mMinutes / 60.0f; mChanged = true; + + updateContentDescription(mCalendar); } private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @@ -243,4 +246,11 @@ public class AnalogClock extends View { 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 3f5b571c467c..a0eba9ac1280 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -371,16 +371,6 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList } } - @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 1bbc50152a8d..324dfd73574a 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -725,16 +725,6 @@ public class HorizontalScrollView extends FrameLayout { 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 61ea5c9c211a..3ac4e80379ff 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -730,16 +730,6 @@ public class ScrollView extends FrameLayout { 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 ac9535a425d8..ce171840dd4a 100644 --- a/core/java/android/widget/SpellChecker.java +++ b/core/java/android/widget/SpellChecker.java @@ -30,8 +30,6 @@ import android.view.textservice.TextServicesManager; 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 @@ public class SpellChecker implements SpellCheckerSessionListener { 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 @@ public class SpellChecker implements SpellCheckerSessionListener { 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; + } + } + + 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; + } } - return suggestions; + + 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 5cd79024f7ad..17f0e0585690 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -353,6 +353,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - /** - * 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Start a new selection if (!handled) { - handled = startSelectionActionMode(); + vibrate = handled = startSelectionActionMode(); } if (vibrate) { @@ -9930,7 +9952,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - // 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 7444d46178a6..f52e7739e9a3 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -237,9 +237,7 @@ public class TimePicker extends FrameLayout { } // 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 ecda47e11134..edf4443b84a2 100644 --- a/core/java/com/android/internal/view/StandaloneActionMode.java +++ b/core/java/com/android/internal/view/StandaloneActionMode.java @@ -36,17 +36,19 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call 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 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call 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 4a38775a32a6..4d1276c54368 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.app.admin.DevicePolicyManager; 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 @@ import java.util.concurrent.atomic.AtomicBoolean; */ 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 class LockPatternUtils { 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"; @@ -434,7 +441,7 @@ public class LockPatternUtils { * 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 +684,9 @@ public class LockPatternUtils { 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 +820,7 @@ public class LockPatternUtils { || backupMode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; return savedPasswordExists() && (passwordEnabled || - (isBiometricEnabled() && backupEnabled)); + (usingBiometricWeak() && backupEnabled)); } /** @@ -824,16 +834,36 @@ public class LockPatternUtils { 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 18bd754470f0..da055fcf84fb 100644 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -392,10 +392,20 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) { 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 @@ static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, }
size_t size = bitmap->getSize();
- bitmap->lockPixels();
- void* pDst = p->writeInplace(size);
- const void* pSrc = bitmap->getPixels();
+ 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();
+ 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 494a2b33ade2..1718e741d8d0 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -697,6 +697,10 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err) 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 @@ static void android_os_Parcel_setDataSize(JNIEnv* env, jobject clazz, jint size) 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 @@ static void android_os_Parcel_setDataCapacity(JNIEnv* env, jobject clazz, jint s 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 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jobject clazz, 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 @@ static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val) 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 @@ static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val) 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 @@ static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val) 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 @@ static void android_os_Parcel_writeDouble(JNIEnv* env, jobject clazz, jdouble va 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 @@ static void android_os_Parcel_writeString(JNIEnv* env, jobject clazz, jstring va err = parcel->writeString16(NULL, 0); } if (err != NO_ERROR) { - jniThrowException(env, "java/lang/OutOfMemoryError", NULL); + signalExceptionForError(env, clazz, err); } } } @@ -1397,7 +1420,7 @@ static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobj 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 @@ static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jobject clazz, jo 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 @@ static void android_os_Parcel_appendFrom(JNIEnv* env, jobject clazz, jobject par 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 @@ static const JNINativeMethod gParcelMethods[] = { {"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 000000000000..eb093e787beb --- /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 c990125afef9..a27abb3ba758 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 b6e213c79f27..13de1c95b64e 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -250,7 +250,7 @@ please see styles_device_defaults.xml. </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 16171dccf7b4..9983f38c9719 100755 --- a/data/sounds/AudioPackage7.mk +++ b/data/sounds/AudioPackage7.mk @@ -27,17 +27,24 @@ PRODUCT_COPY_FILES += \ $(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/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/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/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.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 @@ PRODUCT_COPY_FILES += \ $(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 Binary files differnew file mode 100644 index 000000000000..8b83285af0f6 --- /dev/null +++ b/data/sounds/notifications/ogg/Arcturus.ogg diff --git a/data/sounds/notifications/ogg/Capella.ogg b/data/sounds/notifications/ogg/Capella.ogg Binary files differnew file mode 100755 index 000000000000..88a955d159bc --- /dev/null +++ b/data/sounds/notifications/ogg/Capella.ogg diff --git a/data/sounds/notifications/ogg/CetiAlpha.ogg b/data/sounds/notifications/ogg/CetiAlpha.ogg Binary files differnew file mode 100644 index 000000000000..cd09526335db --- /dev/null +++ b/data/sounds/notifications/ogg/CetiAlpha.ogg diff --git a/data/sounds/notifications/ogg/Polaris.ogg b/data/sounds/notifications/ogg/Polaris.ogg Binary files differnew file mode 100755 index 000000000000..0f63a65bcdb0 --- /dev/null +++ b/data/sounds/notifications/ogg/Polaris.ogg diff --git a/data/sounds/notifications/ogg/Procyon.ogg b/data/sounds/notifications/ogg/Procyon.ogg Binary files differnew file mode 100755 index 000000000000..e5ffcdb15a2d --- /dev/null +++ b/data/sounds/notifications/ogg/Procyon.ogg diff --git a/data/sounds/notifications/ogg/Vega.ogg b/data/sounds/notifications/ogg/Vega.ogg Binary files differnew file mode 100644 index 000000000000..7cdbf213625c --- /dev/null +++ b/data/sounds/notifications/ogg/Vega.ogg diff --git a/data/sounds/ringtones/ogg/Acheron.ogg b/data/sounds/ringtones/ogg/Acheron.ogg Binary files differnew file mode 100644 index 000000000000..67d73884648e --- /dev/null +++ b/data/sounds/ringtones/ogg/Acheron.ogg diff --git a/data/sounds/ringtones/ogg/Nasqueron.ogg b/data/sounds/ringtones/ogg/Nasqueron.ogg Binary files differnew file mode 100644 index 000000000000..ae1a7258529a --- /dev/null +++ b/data/sounds/ringtones/ogg/Nasqueron.ogg diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 464430bb0bd9..1e3e275d864b 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> + <span class="en">XML Layouts</span> + </a></li> + <li><a href="<?cs var:toroot ?>guide/topics/ui/ui-events.html"> + <span class="en">Input Events</span> </a></li> <li><a href="<?cs var:toroot ?>guide/topics/ui/menus.html"> - <span class="en">Creating Menus</span> + <span class="en">Menus</span> </a></li> <li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html"> - <span class="en">Using the Action Bar</span> + <span class="en">Action Bar</span> </a></li> <li><a href="<?cs var:toroot ?>guide/topics/ui/dialogs.html"> - <span class="en">Creating Dialogs</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">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 dedc16fecf71..6c734264c1a9 100644 --- a/docs/html/guide/practices/design/seamlessness.jd +++ b/docs/html/guide/practices/design/seamlessness.jd @@ -171,7 +171,7 @@ interface they've come to expect. When designing your UIs, you should try and 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 7751a7b46efa..3edf33fe3759 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 @@ or device to another. <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 22283cdc306b..20ce701b5120 100644 --- a/docs/html/guide/topics/appwidgets/index.jd +++ b/docs/html/guide/topics/appwidgets/index.jd @@ -297,8 +297,7 @@ Guidelines</a>.</p> <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 3908a7c48e9f..8f619454e120 100644 --- a/docs/html/guide/topics/fundamentals/fragments.jd +++ b/docs/html/guide/topics/fundamentals/fragments.jd @@ -631,8 +631,9 @@ selects a menu item. If the activity's implementation of the on-item-selected ca 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 2490e392e440..f0a923af078e 100644 --- a/docs/html/guide/topics/graphics/index.jd +++ b/docs/html/guide/topics/graphics/index.jd @@ -150,7 +150,7 @@ use your Canvas to draw a Bitmap handled by the system.</p> <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 b0695210b0e0..286e3d1280a3 100644 --- a/docs/html/guide/topics/resources/layout-resource.jd +++ b/docs/html/guide/topics/resources/layout-resource.jd @@ -7,7 +7,7 @@ parent.link=available-resources.html <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 @@ or {@code "wrap_content"}). See the <a href="#layoutvalues">valid values</a> bel </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 @@ deprecate <code>fill_parent</code>.</td> <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 @@ public void onCreate(Bundle savedInstanceState) { <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 36e12f666444..9affb153b2c2 100755 --- a/docs/html/guide/topics/resources/localization.jd +++ b/docs/html/guide/topics/resources/localization.jd @@ -52,7 +52,7 @@ defaults.</li> <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 5b90ce2fd181..64cdf21e4c56 100644 --- a/docs/html/guide/topics/resources/menu-resource.jd +++ b/docs/html/guide/topics/resources/menu-resource.jd @@ -7,7 +7,7 @@ parent.link=available-resources.html <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 @@ parent.link=available-resources.html <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 @@ Avoid using this unless it's critical that the item always appear in the action 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 def727c885fb..f6252dba3ee9 100644 --- a/docs/html/guide/topics/resources/style-resource.jd +++ b/docs/html/guide/topics/resources/style-resource.jd @@ -7,7 +7,7 @@ parent.link=available-resources.html <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 @@ A style can be applied to an individual {@link android.view.View} (from within a 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 d869a44ba67a..27409d59ed5d 100644 --- a/docs/html/guide/topics/search/search-dialog.jd +++ b/docs/html/guide/topics/search/search-dialog.jd @@ -748,8 +748,8 @@ with some callback methods and event listeners. For more information, see the re 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 @@ handle the "Search" menu item and open the search dialog by calling {@link 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 6f12b95082fd..4742923891c8 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 @@ href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery <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 @@ action items and the overflow menu.</p> <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 @@ doing so, because it can create a cluttered UI if there are too many action item 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 @@ Bar completely, use the following style attributes:</p> </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 900e08b10e94..be82dbcc46aa 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 4a574be82244..4dc915f0683d 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 c1272b65eff1..16f14cbc7ae4 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 0329c192e5ef..93753cc0846d 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 @@ DraggableDot.java</a> in <a href="{@docRoot}resources/samples/ApiDemos/index.htm <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 375c9feafa26..d3060c587eea 100644 --- a/docs/html/guide/topics/ui/index.jd +++ b/docs/html/guide/topics/ui/index.jd @@ -9,7 +9,7 @@ page.title=User Interface <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 @@ the Android system initializes these run-time objects, corresponding to the elem 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 @@ Some widgets provided by Android are more complex, like a date picker, a clock, 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 @@ so your only chance to define them is when you </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 @@ method will be called by the framework.</p> <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 @@ applied to specific activities or the entire application.</li> <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 984bf8fcd202..29482444d8e8 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 @@ parent.link=index.html <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 @@ cannot take focus, so you should never use focus as the basis for modifying 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 8fc57fc750d3..c61d4f010f35 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 @@ to the screen. A toast can not accept user interaction events; if you'd like 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 @@ while your Activity is still in focus, consider using a <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 @@ You can use also use dialogs as integral components 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 f12c5eefc950..7bc1cde3ff36 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 0d3e10c0ac14..1a1fb1ff875b 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 a213bea68a80..d787492d8104 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 7d7bfafc2898..93bad43a32ef 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 @@ been registered is triggered by user interaction with the item in the UI.</p> <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 @@ default event handler in the View. So be certain that you want to terminate the <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 854731fa0dc5..fed40abb267e 100644 --- a/docs/html/guide/tutorials/notepad/notepad-ex2.jd +++ b/docs/html/guide/tutorials/notepad/notepad-ex2.jd @@ -299,7 +299,8 @@ case ACTIVITY_EDIT: 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 b211db0ee6f5..c72343a01a3a 100644 --- a/docs/html/resources/faq/commontasks.jd +++ b/docs/html/resources/faq/commontasks.jd @@ -268,7 +268,8 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data){ {@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 @@ focus to the notification before they can interact with it.</p> 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 499b796c3cd5..7e3288f1ced0 100644 --- a/docs/html/resources/tutorials/notepad/notepad-ex2.jd +++ b/docs/html/resources/tutorials/notepad/notepad-ex2.jd @@ -299,7 +299,8 @@ case ACTIVITY_EDIT: 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 339ce2ded35c..407bc86b570b 100644 --- a/docs/html/search.jd +++ b/docs/html/search.jd @@ -64,11 +64,14 @@ page.title=Search Results // 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 bfe13f01bc7f..3fa2acbdaaaf 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -38,6 +38,9 @@ struct flat_binder_object; // defined in support_p/binder_module.h class Parcel { public: + class ReadableBlob; + class WritableBlob; + Parcel(); ~Parcel(); @@ -46,7 +49,7 @@ public: 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 @@ public: 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 @@ public: // 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 @@ public: // 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 @@ public: 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 @@ private: 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 81f818b75d22..0b75b1926c1d 100644 --- a/include/utils/Errors.h +++ b/include/utils/Errors.h @@ -72,6 +72,7 @@ enum { 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 a0fc4d05bc8f..608877eb7dd7 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 @@ status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) mDataPos += len; mDataSize += len; + err = NO_ERROR; + if (numObjects > 0) { // grow objects if (mObjectsCapacity < mObjectsSize + numObjects) { @@ -430,11 +437,28 @@ status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) 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 @@ status_t Parcel::writeDupFileDescriptor(int fd) 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 @@ restart_write: // 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 @@ int Parcel::readFileDescriptor() const 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 @@ status_t Parcel::restartWrite(size_t desired) mNextObjectHint = 0; mHasFds = false; mFdsKnown = true; + mAllowFds = true; return NO_ERROR; } @@ -1434,6 +1536,7 @@ void Parcel::initState() mNextObjectHint = 0; mHasFds = false; mFdsKnown = true; + mAllowFds = true; mOwner = NULL; } @@ -1452,4 +1555,33 @@ void Parcel::scanForFds() const 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 886997c43ac8..c25e3ca07814 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 @@ public class KeyguardViewMediator implements KeyguardViewCallback, */ 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 @@ public class KeyguardViewMediator implements KeyguardViewCallback, private int mLockSoundId; private int mUnlockSoundId; private int mLockSoundStreamId; + private int mMasterStreamMaxVolume; public KeyguardViewMediator(Context context, PhoneWindowManager callback, LocalPowerManager powerManager) { @@ -1061,13 +1070,33 @@ public class KeyguardViewMediator implements KeyguardViewCallback, } 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 f970ff3787be..ca5d27467b3d 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 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler ((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 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // 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 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // 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 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // 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 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler // 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 9205b9ac2d15..2cd6eab0690e 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 968180ccf06d..ed67707d07a6 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLidOpenRotation; int mCarDockRotation; int mDeskDockRotation; + int mHdmiRotation; int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE; int mUserRotation = Surface.ROTATION_0; @@ -777,6 +778,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { ? 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 883fc7175ebb..660681bbdfd2 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -149,6 +149,8 @@ public class WifiService extends IWifiManager.Stub { 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 @@ public class WifiService extends IWifiManager.Stub { 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 eb135b7c41a0..19dd606fe188 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -753,7 +753,7 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 18d6eaa20d96..568a48500d28 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -100,6 +100,7 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { * 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { writeIpAndProxyConfigurations(); sendConfiguredNetworksChangedBroadcast(); } else { - Log.e(TAG, "Failed to remove network " + netId); + loge("Failed to remove network " + netId); } } @@ -404,7 +405,7 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { /* Ignore */ break; default: - Log.e(TAG, "Ignore invalid ip assignment while writing"); + loge("Ignore invalid ip assignment while writing"); break; } @@ -707,7 +708,7 @@ class WifiConfigStore { /* 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { } 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { //Ignore break; default: - Log.e(TAG, "Ignore invalid ip assignment while reading"); + loge("Ignore invalid ip assignment while reading"); break; } @@ -840,18 +841,18 @@ class WifiConfigStore { //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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { netId, WifiConfiguration.Protocol.varName, allowedProtocolsString)) { - Log.d(TAG, "failed to set proto: "+ + loge("failed to set proto: "+ allowedProtocolsString); break setVariables; } @@ -937,7 +938,7 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { netId, WifiConfiguration.PairwiseCipher.varName, allowedPairwiseCiphersString)) { - Log.d(TAG, "failed to set pairwise: "+ + loge("failed to set pairwise: "+ allowedPairwiseCiphersString); break setVariables; } @@ -962,7 +963,7 @@ class WifiConfigStore { netId, WifiConfiguration.GroupCipher.varName, allowedGroupCiphersString)) { - Log.d(TAG, "failed to set group: "+ + loge("failed to set group: "+ allowedGroupCiphersString); break setVariables; } @@ -974,7 +975,7 @@ class WifiConfigStore { netId, WifiConfiguration.pskVarName, config.preSharedKey)) { - Log.d(TAG, "failed to set psk"); + loge("failed to set psk"); break setVariables; } @@ -988,9 +989,7 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { 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 @@ class WifiConfigStore { /* Ignore */ break; default: - Log.e(TAG, "Ignore invalid ip assignment during write"); + loge("Ignore invalid ip assignment during write"); break; } @@ -1154,7 +1149,7 @@ class WifiConfigStore { /* Ignore */ break; default: - Log.e(TAG, "Ignore invalid proxy configuration during write"); + loge("Ignore invalid proxy configuration during write"); break; } @@ -1163,7 +1158,7 @@ class WifiConfigStore { } 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 @@ class WifiConfigStore { } 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 @@ class WifiConfigStore { // 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 @@ class WifiConfigStore { 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 d1522fb48ce7..5ca7aff4d773 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -75,7 +75,6 @@ import android.provider.Settings; 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } } } else { - Log.w(TAG, "Misformatted scan result text with " + + loge("Misformatted scan result text with " + result.length + " fields: " + line); } } @@ -1419,15 +1418,15 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { * @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 @@ public class WifiStateMachine extends StateMachine { * 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } private void handleFailedIpConfiguration() { - Log.e(TAG, "IP configuration failed"); + loge("IP configuration failed"); mWifiInfo.setInetAddress(null); /** @@ -1668,7 +1675,7 @@ public class WifiStateMachine extends StateMachine { * 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { deferMessage(message); break; default: - Log.e(TAG, "Error! unhandled message" + message); + loge("Error! unhandled message" + message); break; } return HANDLED; @@ -1823,7 +1830,7 @@ public class WifiStateMachine extends StateMachine { @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } 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 @@ public class WifiStateMachine extends StateMachine { @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { //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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } 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 @@ public class WifiStateMachine extends StateMachine { } 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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { /* 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { @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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } @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 @@ public class WifiStateMachine extends StateMachine { 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 @@ public class WifiStateMachine extends StateMachine { } } } + + 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 af8c48642799..5d5b9efd628d 100644 --- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java +++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java @@ -35,7 +35,6 @@ import android.os.SystemClock; 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 @@ import java.util.List; */ 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 @@ public class WifiWatchdogStateMachine extends StateMachine { * (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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { } 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 class WifiWatchdogStateMachine extends StateMachine { public void enter() { resetWatchdogState(); mContext.registerReceiver(mBroadcastReceiver, mIntentFilter); - Slog.i(WWSM_TAG, "WifiWatchdogService enabled"); + if (DBG) log("WifiWatchdogService enabled"); } @Override @@ -574,12 +571,12 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { * @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 @@ public class WifiWatchdogStateMachine extends StateMachine { @Override public void exit() { mContext.unregisterReceiver(mBroadcastReceiver); - Slog.i(WWSM_TAG, "WifiWatchdogService disabled"); + if (DBG) log("WifiWatchdogService disabled"); } } @@ -671,7 +668,7 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { if (idDnsMap.isEmpty()) { if (DBG) { - Slog.d(WWSM_TAG, makeLogString() + " FAILURE"); + log(makeLogString() + " FAILURE"); } transitionTo(mDnsCheckFailureState); return HANDLED; @@ -769,15 +763,15 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { } 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 @@ public class WifiWatchdogStateMachine extends StateMachine { } 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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 @@ public class WifiWatchdogStateMachine extends StateMachine { } // 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 @@ public class WifiWatchdogStateMachine extends StateMachine { } 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 @@ public class WifiWatchdogStateMachine extends StateMachine { } 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 @@ public class WifiWatchdogStateMachine extends StateMachine { } 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 @@ public class WifiWatchdogStateMachine extends StateMachine { 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); + } } |