summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk2
-rw-r--r--CleanSpec.mk1
-rw-r--r--api/14.txt58
-rw-r--r--api/current.txt58
-rw-r--r--cmds/bu/src/com/android/commands/bu/Backup.java7
-rw-r--r--core/java/android/app/ActionBar.java9
-rw-r--r--core/java/android/app/Activity.java36
-rw-r--r--core/java/android/app/ActivityThread.java32
-rw-r--r--core/java/android/app/ContextImpl.java14
-rw-r--r--core/java/android/app/Fragment.java9
-rw-r--r--core/java/android/app/FragmentManager.java6
-rw-r--r--core/java/android/app/FragmentTransaction.java6
-rw-r--r--core/java/android/app/Instrumentation.java3
-rw-r--r--core/java/android/app/IntentService.java6
-rw-r--r--core/java/android/app/LoadedApk.java3
-rw-r--r--core/java/android/app/LoaderManager.java6
-rw-r--r--core/java/android/app/PendingIntent.java4
-rw-r--r--core/java/android/app/Service.java12
-rw-r--r--core/java/android/app/backup/IBackupManager.aidl6
-rw-r--r--core/java/android/content/BroadcastReceiver.java13
-rw-r--r--core/java/android/content/Intent.java29
-rw-r--r--core/java/android/content/IntentFilter.java8
-rw-r--r--core/java/android/content/Loader.java8
-rw-r--r--core/java/android/content/SyncManager.java88
-rw-r--r--core/java/android/hardware/Camera.java24
-rw-r--r--core/java/android/inputmethodservice/KeyboardView.java37
-rw-r--r--core/java/android/net/DhcpStateMachine.java8
-rw-r--r--core/java/android/net/DnsPinger.java36
-rw-r--r--core/java/android/net/NetworkStats.java39
-rw-r--r--core/java/android/net/http/SslError.java104
-rw-r--r--core/java/android/os/AsyncTask.java7
-rw-r--r--core/java/android/os/Build.java10
-rw-r--r--core/java/android/os/Bundle.java51
-rw-r--r--core/java/android/os/Parcel.java6
-rw-r--r--core/java/android/provider/CallLog.java8
-rw-r--r--core/java/android/provider/ContactsContract.java37
-rw-r--r--core/java/android/server/BluetoothAdapterStateMachine.java26
-rwxr-xr-xcore/java/android/server/BluetoothService.java4
-rwxr-xr-xcore/java/android/speech/tts/TextToSpeech.java36
-rw-r--r--core/java/android/text/DynamicLayout.java10
-rw-r--r--core/java/android/text/StaticLayout.java10
-rw-r--r--core/java/android/view/ActionMode.java12
-rw-r--r--core/java/android/view/View.java78
-rw-r--r--core/java/android/view/ViewGroup.java18
-rw-r--r--core/java/android/view/ViewRootImpl.java41
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java167
-rw-r--r--core/java/android/webkit/BrowserFrame.java13
-rw-r--r--core/java/android/webkit/FindActionModeCallback.java8
-rw-r--r--core/java/android/webkit/SelectActionModeCallback.java25
-rw-r--r--core/java/android/webkit/SslCertLookupTable.java30
-rw-r--r--core/java/android/webkit/SslErrorHandlerImpl.java69
-rw-r--r--core/java/android/webkit/WebView.java38
-rw-r--r--core/java/android/widget/ActivityChooserView.java46
-rw-r--r--core/java/android/widget/AdapterView.java22
-rw-r--r--core/java/android/widget/AnalogClock.java10
-rw-r--r--core/java/android/widget/Gallery.java10
-rw-r--r--core/java/android/widget/HorizontalScrollView.java10
-rw-r--r--core/java/android/widget/ScrollView.java10
-rw-r--r--core/java/android/widget/ShareActionProvider.java6
-rw-r--r--core/java/android/widget/SpellChecker.java87
-rw-r--r--core/java/android/widget/TextView.java120
-rw-r--r--core/java/android/widget/TimePicker.java4
-rw-r--r--core/java/com/android/internal/view/StandaloneActionMode.java8
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java72
-rw-r--r--core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java10
-rw-r--r--core/jni/android/graphics/Bitmap.cpp29
-rw-r--r--core/jni/android_util_Binder.cpp52
-rw-r--r--core/res/AndroidManifest.xml17
-rw-r--r--core/res/res/layout/keyguard_screen_password_landscape.xml17
-rw-r--r--core/res/res/layout/keyguard_screen_password_portrait.xml17
-rw-r--r--core/res/res/layout/screen_simple_overlay_action_mode.xml37
-rwxr-xr-xcore/res/res/values/attrs.xml6
-rw-r--r--core/res/res/values/attrs_manifest.xml2
-rwxr-xr-xcore/res/res/values/strings.xml30
-rw-r--r--core/res/res/values/styles.xml2
-rwxr-xr-xcore/res/res/xml/password_kbd_numeric.xml8
-rw-r--r--core/tests/coretests/src/android/net/NetworkStatsTest.java59
-rw-r--r--data/fonts/fonts.xml48
-rwxr-xr-xdata/sounds/AudioPackage7.mk17
-rw-r--r--data/sounds/notifications/ogg/Arcturus.oggbin0 -> 7933 bytes
-rwxr-xr-xdata/sounds/notifications/ogg/Capella.oggbin0 -> 13126 bytes
-rw-r--r--data/sounds/notifications/ogg/CetiAlpha.oggbin0 -> 26158 bytes
-rwxr-xr-xdata/sounds/notifications/ogg/Polaris.oggbin0 -> 20531 bytes
-rwxr-xr-xdata/sounds/notifications/ogg/Procyon.oggbin0 -> 22344 bytes
-rw-r--r--data/sounds/notifications/ogg/Vega.oggbin0 -> 29310 bytes
-rw-r--r--data/sounds/ringtones/ogg/Acheron.oggbin0 -> 88561 bytes
-rw-r--r--data/sounds/ringtones/ogg/Nasqueron.oggbin0 -> 102048 bytes
-rw-r--r--docs/html/guide/guide_toc.cs26
-rw-r--r--docs/html/guide/practices/design/seamlessness.jd2
-rw-r--r--docs/html/guide/practices/ui_guidelines/menu_design.jd4
-rw-r--r--docs/html/guide/topics/appwidgets/index.jd3
-rw-r--r--docs/html/guide/topics/fundamentals/fragments.jd5
-rw-r--r--docs/html/guide/topics/graphics/index.jd2
-rw-r--r--docs/html/guide/topics/resources/layout-resource.jd12
-rwxr-xr-xdocs/html/guide/topics/resources/localization.jd2
-rw-r--r--docs/html/guide/topics/resources/menu-resource.jd18
-rw-r--r--docs/html/guide/topics/resources/style-resource.jd4
-rw-r--r--docs/html/guide/topics/search/search-dialog.jd8
-rw-r--r--docs/html/guide/topics/ui/actionbar.jd10
-rw-r--r--docs/html/guide/topics/ui/custom-components.jd2
-rw-r--r--docs/html/guide/topics/ui/declaring-layout.jd2
-rw-r--r--docs/html/guide/topics/ui/dialogs.jd2
-rw-r--r--docs/html/guide/topics/ui/drag-drop.jd4
-rw-r--r--docs/html/guide/topics/ui/index.jd20
-rw-r--r--docs/html/guide/topics/ui/menus.jd8
-rw-r--r--docs/html/guide/topics/ui/notifiers/index.jd19
-rw-r--r--docs/html/guide/topics/ui/notifiers/notifications.jd4
-rw-r--r--docs/html/guide/topics/ui/notifiers/toasts.jd4
-rw-r--r--docs/html/guide/topics/ui/themes.jd2
-rw-r--r--docs/html/guide/topics/ui/ui-events.jd10
-rw-r--r--docs/html/guide/tutorials/notepad/notepad-ex2.jd3
-rw-r--r--docs/html/resources/faq/commontasks.jd5
-rw-r--r--docs/html/resources/resources-data.js10
-rw-r--r--docs/html/resources/tutorials/notepad/notepad-ex2.jd3
-rw-r--r--docs/html/search.jd7
-rw-r--r--include/binder/Parcel.h55
-rw-r--r--include/media/stagefright/OMXCodec.h2
-rw-r--r--include/utils/Errors.h1
-rw-r--r--libs/binder/Parcel.cpp134
-rw-r--r--libs/hwui/Snapshot.h32
-rw-r--r--libs/rs/driver/rsdBcc.cpp5
-rwxr-xr-xmedia/libstagefright/OMXCodec.cpp38
-rw-r--r--packages/SystemUI/res/values/dimens.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java12
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java35
-rw-r--r--policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java31
-rw-r--r--policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java35
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java10
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java9
-rw-r--r--services/java/com/android/server/BackupManagerService.java39
-rw-r--r--services/java/com/android/server/EventLogTags.logtags4
-rw-r--r--services/java/com/android/server/NetworkManagementService.java83
-rw-r--r--services/java/com/android/server/WifiService.java11
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java333
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java8
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--services/tests/servicestests/res/raw/xt_qtaguid_iface_typical6
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java54
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java2
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java53
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java312
-rw-r--r--wifi/java/android/net/wifi/WifiConfigStore.java95
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java278
-rw-r--r--wifi/java/android/net/wifi/WifiWatchdogStateMachine.java106
145 files changed, 2700 insertions, 1431 deletions
diff --git a/Android.mk b/Android.mk
index be8c25b714a1..c8b2555487ca 100644
--- a/Android.mk
+++ b/Android.mk
@@ -400,6 +400,8 @@ web_docs_sample_code_flags := \
resources/samples/AccessibilityService "Accessibility Service" \
-samplecode $(sample_dir)/AccelerometerPlay \
resources/samples/AccelerometerPlay "Accelerometer Play" \
+ -samplecode $(sample_dir)/AndroidBeam \
+ resources/samples/AndroidBeam "Android Beam" \
-samplecode $(sample_dir)/ApiDemos \
resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/Support4Demos \
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/api/14.txt b/api/14.txt
index 9f2a6dfc3855..e26311f42882 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -16583,10 +16583,6 @@ package android.provider {
field public static final java.lang.String PHOTO_FILE_ID = "data14";
}
- public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.ContactsColumns {
field public static final java.lang.String DISPLAY_NAME = "display_name";
field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@ package android.provider {
field public static final java.lang.String DATA_ID = "data_id";
}
- public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.RawContactsColumns {
field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@ package android.provider {
field public static final android.net.Uri PROFILE_CONTENT_URI;
}
- public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO = "photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
- field public static final java.lang.String PHOTO_URI = "photo_uri";
- field public static final java.lang.String SORT_INDEX = "sort_index";
- field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
- field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
- }
-
- public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
- field public static final android.net.Uri CONTENT_LIMIT_URI;
- field public static final android.net.Uri CONTENT_PHOTO_URI;
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
- field public static final android.net.Uri CONTENT_URI;
- field public static final java.lang.String MAX_ITEMS = "max_items";
- }
-
- public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "photo";
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemsColumns {
- field public static final java.lang.String ACCOUNT_NAME = "account_name";
- field public static final java.lang.String ACCOUNT_TYPE = "account_type";
- field public static final java.lang.String COMMENTS = "comments";
- field public static final java.lang.String CONTACT_ID = "contact_id";
- field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
- field public static final java.lang.String DATA_SET = "data_set";
- field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
- field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
- field public static final java.lang.String RES_ICON = "icon";
- field public static final java.lang.String RES_LABEL = "label";
- field public static final java.lang.String RES_PACKAGE = "res_package";
- field public static final java.lang.String SYNC1 = "stream_item_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_sync4";
- field public static final java.lang.String TEXT = "text";
- field public static final java.lang.String TIMESTAMP = "timestamp";
- }
-
protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
field public static final java.lang.String ACCOUNT_NAME = "account_name";
field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/api/current.txt b/api/current.txt
index 9f2a6dfc3855..e26311f42882 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16583,10 +16583,6 @@ package android.provider {
field public static final java.lang.String PHOTO_FILE_ID = "data14";
}
- public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.ContactsColumns {
field public static final java.lang.String DISPLAY_NAME = "display_name";
field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@ package android.provider {
field public static final java.lang.String DATA_ID = "data_id";
}
- public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.RawContactsColumns {
field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@ package android.provider {
field public static final android.net.Uri PROFILE_CONTENT_URI;
}
- public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO = "photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
- field public static final java.lang.String PHOTO_URI = "photo_uri";
- field public static final java.lang.String SORT_INDEX = "sort_index";
- field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
- field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
- }
-
- public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
- field public static final android.net.Uri CONTENT_LIMIT_URI;
- field public static final android.net.Uri CONTENT_PHOTO_URI;
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
- field public static final android.net.Uri CONTENT_URI;
- field public static final java.lang.String MAX_ITEMS = "max_items";
- }
-
- public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "photo";
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemsColumns {
- field public static final java.lang.String ACCOUNT_NAME = "account_name";
- field public static final java.lang.String ACCOUNT_TYPE = "account_type";
- field public static final java.lang.String COMMENTS = "comments";
- field public static final java.lang.String CONTACT_ID = "contact_id";
- field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
- field public static final java.lang.String DATA_SET = "data_set";
- field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
- field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
- field public static final java.lang.String RES_ICON = "icon";
- field public static final java.lang.String RES_LABEL = "label";
- field public static final java.lang.String RES_PACKAGE = "res_package";
- field public static final java.lang.String SYNC1 = "stream_item_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_sync4";
- field public static final java.lang.String TEXT = "text";
- field public static final java.lang.String TIMESTAMP = "timestamp";
- }
-
protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
field public static final java.lang.String ACCOUNT_NAME = "account_name";
field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java
index 4c4bf9863aea..046ccca9b02a 100644
--- a/cmds/bu/src/com/android/commands/bu/Backup.java
+++ b/cmds/bu/src/com/android/commands/bu/Backup.java
@@ -66,6 +66,7 @@ public final class Backup {
boolean saveApks = false;
boolean saveShared = false;
boolean doEverything = false;
+ boolean allIncludesSystem = true;
String arg;
while ((arg = nextArg()) != null) {
@@ -78,6 +79,10 @@ public final class Backup {
saveShared = true;
} else if ("-noshared".equals(arg)) {
saveShared = false;
+ } else if ("-system".equals(arg)) {
+ allIncludesSystem = true;
+ } else if ("-nosystem".equals(arg)) {
+ allIncludesSystem = false;
} else if ("-all".equals(arg)) {
doEverything = true;
} else {
@@ -102,7 +107,7 @@ public final class Backup {
try {
ParcelFileDescriptor fd = ParcelFileDescriptor.adoptFd(socketFd);
String[] packArray = new String[packages.size()];
- mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything,
+ mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything, allIncludesSystem,
packages.toArray(packArray));
} catch (RemoteException e) {
Log.e(TAG, "Unable to invoke backup manager for backup");
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 51c6f3adbbb3..24d3a6b3045d 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -43,15 +43,18 @@ import android.widget.SpinnerAdapter;
* modify various characteristics of the action bar or remove it completely.</p>
* <p>From your activity, you can retrieve an instance of {@link ActionBar} by calling {@link
* android.app.Activity#getActionBar getActionBar()}.</p>
- * <p>For information about how to use the action bar, including how to add action items, navigation
- * modes and more, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
- * Bar</a> developer guide.</p>
* <p>In some cases, the action bar may be overlayed by another bar that enables contextual actions,
* using an {@link android.view.ActionMode}. For example, when the user selects one or more items in
* your activity, you can enable an action mode that offers actions specific to the selected
* items, with a UI that temporarily replaces the action bar. Although the UI may occupy the
* same space, the {@link android.view.ActionMode} APIs are distinct and independent from those for
* {@link ActionBar}.
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to use the action bar, including how to add action items, navigation
+ * modes and more, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
+ * Bar</a> developer guide.</p>
+ * </div>
*/
public abstract class ActionBar {
/**
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 034e3c787766..8e8d37d645c9 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -111,18 +111,6 @@ import java.util.HashMap;
* {@link android.R.styleable#AndroidManifestActivity &lt;activity&gt;}
* declaration in their package's <code>AndroidManifest.xml</code>.</p>
*
- * <p>The Activity class is an important part of an application's overall lifecycle,
- * and the way activities are launched and put together is a fundamental
- * part of the platform's application model. For a detailed perspective on the structure of an
- * Android application and how activities behave, please read the
- * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and
- * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
- * documents.</p>
- *
- * <p>You can also find a detailed discussion about how to create activities in the
- * <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
- * document.</p>
- *
* <p>Topics covered here:
* <ol>
* <li><a href="#Fragments">Fragments</a>
@@ -133,7 +121,22 @@ import java.util.HashMap;
* <li><a href="#Permissions">Permissions</a>
* <li><a href="#ProcessLifecycle">Process Lifecycle</a>
* </ol>
- *
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>The Activity class is an important part of an application's overall lifecycle,
+ * and the way activities are launched and put together is a fundamental
+ * part of the platform's application model. For a detailed perspective on the structure of an
+ * Android application and how activities behave, please read the
+ * <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> and
+ * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
+ * developer guides.</p>
+ *
+ * <p>You can also find a detailed discussion about how to create activities in the
+ * <a href="{@docRoot}guide/topics/fundamentals/activities.html">Activities</a>
+ * developer guide.</p>
+ * </div>
+ *
* <a name="Fragments"></a>
* <h3>Fragments</h3>
*
@@ -3246,6 +3249,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 +3374,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 +3424,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 +3698,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 +3821,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..d2facdcc172c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1478,7 +1478,7 @@ public final class ActivityThread {
}
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
- DisplayMetrics metrics = getDisplayMetricsLocked(compInfo, false);
+ DisplayMetrics metrics = getDisplayMetricsLocked(null, false);
r = new Resources(assets, metrics, getConfiguration(), compInfo);
if (false) {
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
@@ -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);
}
@@ -3473,7 +3476,7 @@ public final class ActivityThread {
return false;
}
int changes = mResConfiguration.updateFrom(config);
- DisplayMetrics dm = getDisplayMetricsLocked(compat, true);
+ DisplayMetrics dm = getDisplayMetricsLocked(null, true);
if (compat != null && (mResCompatibilityInfo == null ||
!mResCompatibilityInfo.equals(compat))) {
@@ -3514,7 +3517,20 @@ public final class ActivityThread {
return changes != 0;
}
-
+
+ final Configuration applyCompatConfiguration() {
+ Configuration config = mConfiguration;
+ if (mCompatConfiguration == null) {
+ mCompatConfiguration = new Configuration();
+ }
+ mCompatConfiguration.setTo(mConfiguration);
+ if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
+ mResCompatibilityInfo.applyToConfiguration(mCompatConfiguration);
+ config = mCompatConfiguration;
+ }
+ return config;
+ }
+
final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
ArrayList<ComponentCallbacks2> callbacks = null;
@@ -3543,14 +3559,7 @@ public final class ActivityThread {
return;
}
mConfiguration.updateFrom(config);
- if (mCompatConfiguration == null) {
- mCompatConfiguration = new Configuration();
- }
- mCompatConfiguration.setTo(mConfiguration);
- if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
- mResCompatibilityInfo.applyToConfiguration(mCompatConfiguration);
- config = mCompatConfiguration;
- }
+ config = applyCompatConfiguration();
callbacks = collectComponentCallbacksLocked(false, config);
}
@@ -3749,6 +3758,7 @@ public final class ActivityThread {
* in AppBindData can be safely assumed to be up to date
*/
applyConfigurationToResourcesLocked(data.config, data.compatInfo);
+ applyCompatConfiguration();
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
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/Fragment.java b/core/java/android/app/Fragment.java
index 3a08e6d4ee17..d423d9870577 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -162,9 +162,6 @@ final class FragmentState implements Parcelable {
* constructor to instantiate it. If the empty constructor is not available,
* a runtime exception will occur in some cases during state restore.
*
- * <p>For more documentation, also see the <a
- * href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
- *
* <p>Topics covered here:
* <ol>
* <li><a href="#OlderPlatforms">Older Platforms</a>
@@ -173,6 +170,12 @@ final class FragmentState implements Parcelable {
* <li><a href="#BackStack">Back Stack</a>
* </ol>
*
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using fragments, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ * </div>
+ *
* <a name="OlderPlatforms"></a>
* <h3>Older Platforms</h3>
*
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 7a6759f9f084..3da4f29aeb28 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -45,6 +45,12 @@ import java.util.Arrays;
/**
* Interface for interacting with {@link Fragment} objects inside of an
* {@link Activity}
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using fragments, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ * </div>
*/
public abstract class FragmentManager {
/**
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index c1f3cd61da1d..6e9989968896 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -2,6 +2,12 @@ package android.app;
/**
* API for performing a set of Fragment operations.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using fragments, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ * </div>
*/
public abstract class FragmentTransaction {
/**
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/IntentService.java b/core/java/android/app/IntentService.java
index 57a26959bc8c..96767aebfe92 100644
--- a/core/java/android/app/IntentService.java
+++ b/core/java/android/app/IntentService.java
@@ -41,6 +41,12 @@ import android.os.Message;
* long as necessary (and will not block the application's main loop), but
* only one request will be processed at a time.
*
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a detailed discussion about how to create services, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a> developer guide.</p>
+ * </div>
+ *
* @see android.os.AsyncTask
*/
public abstract class IntentService extends Service {
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/LoaderManager.java b/core/java/android/app/LoaderManager.java
index 46a008d58e9d..89e9dddc1456 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -47,6 +47,12 @@ import java.lang.reflect.Modifier;
*
* {@sample development/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.java
* fragment_cursor}
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using loaders, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
+ * </div>
*/
public abstract class LoaderManager {
/**
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/app/Service.java b/core/java/android/app/Service.java
index ebde6e099cd0..35bd8c08a713 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -50,10 +50,6 @@ import java.io.PrintWriter;
* Threads</a>. The {@link IntentService} class is available
* as a standard implementation of Service that has its own thread where it
* schedules its work to be done.</p>
- *
- * <p>You can find a detailed discussion about how to create services in the
- * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a>
- * document.</p>
*
* <p>Topics covered here:
* <ol>
@@ -64,7 +60,13 @@ import java.io.PrintWriter;
* <li><a href="#LocalServiceSample">Local Service Sample</a>
* <li><a href="#RemoteMessengerServiceSample">Remote Messenger Service Sample</a>
* </ol>
- *
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For a detailed discussion about how to create services, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a> developer guide.</p>
+ * </div>
+ *
* <a name="WhatIsAService"></a>
* <h3>What is a Service?</h3>
*
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index c154296fbf03..acdd0b54559a 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -157,11 +157,15 @@ interface IBackupManager {
* @param allApps If <code>true</code>, the resulting tar stream will include all
* installed applications' data, not just those named in the <code>packageNames</code>
* parameter.
+ * @param allIncludesSystem If {@code true}, then {@code allApps} will be interpreted
+ * as including packages pre-installed as part of the system. If {@code false},
+ * then setting {@code allApps} to {@code true} will mean only that all 3rd-party
+ * applications will be included in the dataset.
* @param packageNames The package names of the apps whose data (and optionally .apk files)
* are to be backed up. The <code>allApps</code> parameter supersedes this.
*/
void fullBackup(in ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
- boolean allApps, in String[] packageNames);
+ boolean allApps, boolean allIncludesSystem, in String[] packageNames);
/**
* Restore device content from the data stream passed through the given socket. The
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index 028149b3760b..d71a8d6f73a1 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -90,7 +90,14 @@ import android.util.Slog;
* <li><a href="#Permissions">Permissions</a>
* <li><a href="#ProcessLifecycle">Process Lifecycle</a>
* </ol>
- *
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to use this class to receive and resolve intents, read the
+ * <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ * developer guide.</p>
+ * </div>
+ *
* <a name="ReceiverLifecycle"></a>
* <h3>Receiver Lifecycle</h3>
*
@@ -366,6 +373,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 +472,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..2be515376453 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -55,13 +55,21 @@ import java.util.Set;
* {@link android.content.Context#bindService} to communicate with a
* background {@link android.app.Service}.
*
- * <p>An Intent provides a facility for performing late runtime binding between
- * the code in different applications. Its most significant use is in the
- * launching of activities, where it can be thought of as the glue between
- * activities. It is
- * basically a passive data structure holding an abstract description of an
- * action to be performed. The primary pieces of information in an intent
- * are:</p>
+ * <p>An Intent provides a facility for performing late runtime binding between the code in
+ * different applications. Its most significant use is in the launching of activities, where it
+ * can be thought of as the glue between activities. It is basically a passive data structure
+ * holding an abstract description of an action to be performed.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to create and resolve intents, read the
+ * <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ * developer guide.</p>
+ * </div>
+ *
+ * <a name="IntentStructure"></a>
+ * <h3>Intent Structure</h3>
+ * <p>The primary pieces of information in an intent are:</p>
*
* <ul>
* <li> <p><b>action</b> -- The general action to be performed, such as
@@ -3568,6 +3576,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/IntentFilter.java b/core/java/android/content/IntentFilter.java
index f9b3fd512505..3b0d846cd235 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -71,6 +71,14 @@ import java.util.Set;
* To specify a path, you also must specify both one or more authorities and
* one or more schemes it is associated with.
*
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about how to create and resolve intents, read the
+ * <a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+ * developer guide.</p>
+ * </div>
+ *
+ * <h3>Filter Rules</h3>
* <p>A match is based on the following rules. Note that
* for an IntentFilter to match an Intent, three conditions must hold:
* the <strong>action</strong> and <strong>category</strong> must match, and
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 368c33e18743..b962800da915 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -40,8 +40,12 @@ import java.io.PrintWriter;
*
* <p>Most implementations should not derive directly from this class, but
* instead inherit from {@link AsyncTaskLoader}.</p>
- * <p>For more information, see the <a
- * href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using loaders, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
+ * </div>
*
* @param <D> The result returned when the load is complete
*/
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/hardware/Camera.java b/core/java/android/hardware/Camera.java
index e40de266606c..c3a14ca537f3 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -201,7 +201,7 @@ public class Camera {
public static final int CAMERA_FACING_FRONT = 1;
/**
- * The direction that the camera faces to. It should be
+ * The direction that the camera faces. It should be
* CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
*/
public int facing;
@@ -1055,9 +1055,9 @@ public class Camera {
/**
* Notify the listener of the detected faces in the preview frame.
*
- * @param faces the detected faces. The list is sorted by the score.
- * The highest score is the first element.
- * @param camera the Camera service object
+ * @param faces The detected faces in a list sorted by the confidence score.
+ * The highest scored face is the first element.
+ * @param camera The {@link Camera} service object
*/
void onFaceDetection(Face[] faces, Camera camera);
}
@@ -1105,7 +1105,7 @@ public class Camera {
/**
* Stops the face detection.
*
- * @see #startFaceDetection(int)
+ * @see #startFaceDetection()
*/
public final void stopFaceDetection() {
_stopFaceDetection();
@@ -1116,8 +1116,12 @@ public class Camera {
private native final void _stopFaceDetection();
/**
- * The information of a face from camera face detection.
+ * Information about a face identified through camera face detection.
+ *
+ * <p>When face detection is used with a camera, the {@link FaceDetectionListener} returns a
+ * list of face objects for use in focusing and metering.</p>
*
+ * @see FaceDetectionListener
*/
public static class Face {
/**
@@ -1138,15 +1142,15 @@ public class Camera {
* the sensor sees. The direction is not affected by the rotation or
* mirroring of {@link #setDisplayOrientation(int)}.</p>
*
- * @see #startFaceDetection(int)
+ * @see #startFaceDetection()
*/
public Rect rect;
/**
- * The confidence level of the face. The range is 1 to 100. 100 is the
+ * The confidence level for the detection of the face. The range is 1 to 100. 100 is the
* highest confidence.
*
- * @see #startFaceDetection(int)
+ * @see #startFaceDetection()
*/
public int score;
@@ -3144,7 +3148,7 @@ public class Camera {
* supported.
*
* @return the maximum number of detected face supported by the camera.
- * @see #startFaceDetection(int)
+ * @see #startFaceDetection()
*/
public int getMaxNumDetectedFaces() {
return getInt(KEY_MAX_NUM_DETECTED_FACES_HW, 0);
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 1119c1eb1b31..5343e2a5f1bc 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -248,6 +248,8 @@ public class KeyboardView extends View implements View.OnClickListener {
private AccessibilityManager mAccessibilityManager;
/** The audio manager for accessibility support */
private AudioManager mAudioManager;
+ /** Whether the requirement of a headset to hear passwords if accessibility is enabled is announced. */
+ private boolean mHeadsetRequiredToHearPasswordsAnnounced;
Handler mHandler = new Handler() {
@Override
@@ -852,13 +854,15 @@ public class KeyboardView extends View implements View.OnClickListener {
Key oldKey = keys[oldKeyIndex];
oldKey.onReleased(mCurrentKeyIndex == NOT_A_KEY);
invalidateKey(oldKeyIndex);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT, oldKey.codes[0]);
+ sendAccessibilityEventForUnicodeCharacter(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT,
+ oldKey.codes[0]);
}
if (mCurrentKeyIndex != NOT_A_KEY && keys.length > mCurrentKeyIndex) {
Key newKey = keys[mCurrentKeyIndex];
newKey.onPressed();
invalidateKey(mCurrentKeyIndex);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER, newKey.codes[0]);
+ sendAccessibilityEventForUnicodeCharacter(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
+ newKey.codes[0]);
}
}
// If key changed and preview is on ...
@@ -958,13 +962,13 @@ public class KeyboardView extends View implements View.OnClickListener {
mPreviewText.setVisibility(VISIBLE);
}
- private void sendAccessibilityEvent(int eventType, int code) {
+ private void sendAccessibilityEventForUnicodeCharacter(int eventType, int code) {
if (mAccessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
onInitializeAccessibilityEvent(event);
+ String text = null;
// Add text only if headset is used to avoid leaking passwords.
if (mAudioManager.isBluetoothA2dpOn() || mAudioManager.isWiredHeadsetOn()) {
- String text = null;
switch (code) {
case Keyboard.KEYCODE_ALT:
text = mContext.getString(R.string.keyboardview_keycode_alt);
@@ -990,11 +994,17 @@ public class KeyboardView extends View implements View.OnClickListener {
default:
text = String.valueOf((char) code);
}
- event.getText().add(text);
+ } else if (!mHeadsetRequiredToHearPasswordsAnnounced) {
+ // We want the waring for required head set to be send with both the
+ // hover enter and hover exit event, so set the flag after the exit.
+ if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
+ mHeadsetRequiredToHearPasswordsAnnounced = true;
+ }
+ text = mContext.getString(R.string.keyboard_headset_required_to_hear_password);
} else {
- event.getText().add(mContext.getString(
- R.string.keyboard_headset_required_to_hear_password));
+ text = mContext.getString(R.string.keyboard_password_character_no_headset);
}
+ event.getText().add(text);
mAccessibilityManager.sendAccessibilityEvent(event);
}
}
@@ -1134,15 +1144,13 @@ public class KeyboardView extends View implements View.OnClickListener {
}
@Override
- protected boolean dispatchHoverEvent(MotionEvent event) {
+ public boolean onHoverEvent(MotionEvent event) {
// If touch exploring is enabled we ignore touch events and transform
// the stream of hover events as touch events. This allows one consistent
// event stream to drive the keyboard since during touch exploring the
// first touch generates only hover events and tapping on the same
// location generates hover and touch events.
- if (mAccessibilityManager.isEnabled()
- && mAccessibilityManager.isTouchExplorationEnabled()
- && event.getPointerCount() == 1) {
+ if (mAccessibilityManager.isTouchExplorationEnabled() && event.getPointerCount() == 1) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
@@ -1156,9 +1164,9 @@ public class KeyboardView extends View implements View.OnClickListener {
break;
}
onTouchEventInternal(event);
- return true;
+ event.setAction(action);
}
- return super.dispatchHoverEvent(event);
+ return super.onHoverEvent(event);
}
@Override
@@ -1168,8 +1176,7 @@ public class KeyboardView extends View implements View.OnClickListener {
// event stream to drive the keyboard since during touch exploring the
// first touch generates only hover events and tapping on the same
// location generates hover and touch events.
- if (mAccessibilityManager.isEnabled()
- && mAccessibilityManager.isTouchExplorationEnabled()) {
+ if (mAccessibilityManager.isTouchExplorationEnabled()) {
return true;
}
return onTouchEventInternal(event);
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/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index f3be39ca2b76..e5549753cc05 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -272,6 +272,17 @@ public class NetworkStats implements Parcelable {
}
/**
+ * Combine all values from another {@link NetworkStats} into this object.
+ */
+ public void combineAllValues(NetworkStats another) {
+ NetworkStats.Entry entry = null;
+ for (int i = 0; i < another.size; i++) {
+ entry = another.getValues(i, entry);
+ combineValues(entry);
+ }
+ }
+
+ /**
* Find first stats index that matches the requested parameters.
*/
public int findIndex(String iface, int uid, int set, int tag) {
@@ -456,6 +467,34 @@ public class NetworkStats implements Parcelable {
return result;
}
+ /**
+ * Return total statistics grouped by {@link #iface}; doesn't mutate the
+ * original structure.
+ */
+ public NetworkStats groupedByIface() {
+ final NetworkStats stats = new NetworkStats(elapsedRealtime, 10);
+
+ final Entry entry = new Entry();
+ entry.uid = UID_ALL;
+ entry.set = SET_ALL;
+ entry.tag = TAG_NONE;
+ entry.operations = 0L;
+
+ for (int i = 0; i < size; i++) {
+ // skip specific tags, since already counted in TAG_NONE
+ if (tag[i] != TAG_NONE) continue;
+
+ entry.iface = iface[i];
+ entry.rxBytes = rxBytes[i];
+ entry.rxPackets = rxPackets[i];
+ entry.txBytes = txBytes[i];
+ entry.txPackets = txPackets[i];
+ stats.combineValues(entry);
+ }
+
+ return stats;
+ }
+
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix);
pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime);
diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java
index 08c669232c5d..5998f5f9ed6e 100644
--- a/core/java/android/net/http/SslError.java
+++ b/core/java/android/net/http/SslError.java
@@ -19,7 +19,8 @@ package android.net.http;
import java.security.cert.X509Certificate;
/**
- * One or more individual SSL errors and the associated SSL certificate
+ * This class represents a set of one or more SSL errors and the associated SSL
+ * certificate.
*/
public class SslError {
@@ -48,16 +49,17 @@ public class SslError {
*/
public static final int SSL_DATE_INVALID = 4;
/**
- * The certificate is invalid
+ * A generic error occurred
*/
public static final int SSL_INVALID = 5;
/**
- * The number of different SSL errors (update if you add a new SSL error!!!)
+ * The number of different SSL errors.
* @deprecated This constant is not necessary for using the SslError API and
* can change from release to release.
*/
+ // Update if you add a new SSL error!!!
@Deprecated
public static final int SSL_MAX_ERROR = 6;
@@ -78,56 +80,56 @@ public class SslError {
final String mUrl;
/**
- * Creates a new SSL error set object
+ * Creates a new SslError object using the supplied error and certificate.
+ * The URL will be set to the empty string.
* @param error The SSL error
* @param certificate The associated SSL certificate
* @deprecated Use {@link #SslError(int, SslCertificate, String)}
*/
@Deprecated
public SslError(int error, SslCertificate certificate) {
- addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
- mCertificate = certificate;
- mUrl = "";
+ this(error, certificate, "");
}
/**
- * Creates a new SSL error set object
+ * Creates a new SslError object using the supplied error and certificate.
+ * The URL will be set to the empty string.
* @param error The SSL error
* @param certificate The associated SSL certificate
* @deprecated Use {@link #SslError(int, X509Certificate, String)}
*/
@Deprecated
public SslError(int error, X509Certificate certificate) {
- addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
- mCertificate = new SslCertificate(certificate);
- mUrl = "";
+ this(error, certificate, "");
}
/**
- * Creates a new SSL error set object
+ * Creates a new SslError object using the supplied error, certificate and
+ * URL.
* @param error The SSL error
* @param certificate The associated SSL certificate
- * @param url The associated URL.
+ * @param url The associated URL
*/
public SslError(int error, SslCertificate certificate, String url) {
+ assert certificate != null;
+ assert url != null;
addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
mCertificate = certificate;
- if (url == null) {
- throw new NullPointerException("url is null.");
- }
mUrl = url;
}
/**
+ * Creates a new SslError object using the supplied error, certificate and
+ * URL.
+ * @param error The SSL error
+ * @param certificate The associated SSL certificate
+ * @param url The associated URL
+ */
+ public SslError(int error, X509Certificate certificate, String url) {
+ this(error, new SslCertificate(certificate), url);
+ }
+
+ /**
* Creates an SslError object from a chromium error code.
* @param error The chromium error code
* @param certificate The associated SSL certificate
@@ -138,56 +140,38 @@ public class SslError {
int error, SslCertificate cert, String url) {
// The chromium error codes are in:
// external/chromium/net/base/net_error_list.h
- if (error > -200 || error < -299) {
- throw new NullPointerException("Not a valid chromium SSL error code.");
- }
+ assert (error >= -299 && error <= -200);
if (error == -200)
return new SslError(SSL_IDMISMATCH, cert, url);
if (error == -201)
return new SslError(SSL_DATE_INVALID, cert, url);
if (error == -202)
return new SslError(SSL_UNTRUSTED, cert, url);
- // Map all other errors to SSL_INVALID
+ // Map all other codes to SSL_INVALID.
return new SslError(SSL_INVALID, cert, url);
}
/**
- * Creates a new SSL error set object
- * @param error The SSL error
- * @param certificate The associated SSL certificate
- * @param url The associated URL.
- */
- public SslError(int error, X509Certificate certificate, String url) {
- addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
- mCertificate = new SslCertificate(certificate);
- if (url == null) {
- throw new NullPointerException("url is null.");
- }
- mUrl = url;
- }
-
- /**
- * @return The SSL certificate associated with the error set, non-null.
+ * Gets the SSL certificate associated with this object.
+ * @return The SSL certificate, non-null.
*/
public SslCertificate getCertificate() {
return mCertificate;
}
/**
- * @return The URL associated with the error set, non-null.
- * "" if one of the deprecated constructors is used.
+ * Gets the URL associated with this object.
+ * @return The URL, non-null.
*/
public String getUrl() {
return mUrl;
}
/**
- * Adds the SSL error to the error set
+ * Adds the supplied SSL error to the set.
* @param error The SSL error to add
- * @return True iff the error being added is a known SSL error
+ * @return True if the error being added is a known SSL error, otherwise
+ * false.
*/
public boolean addError(int error) {
boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
@@ -199,8 +183,9 @@ public class SslError {
}
/**
- * @param error The SSL error to check
- * @return True iff the set includes the error
+ * Determines whether this object includes the supplied error.
+ * @param error The SSL error to check for
+ * @return True if this object includes the error, otherwise false.
*/
public boolean hasError(int error) {
boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
@@ -212,7 +197,8 @@ public class SslError {
}
/**
- * @return The primary, most severe, SSL error in the set
+ * Gets the most severe SSL error in this object's set of errors.
+ * @return The most severe SSL error.
*/
public int getPrimaryError() {
if (mErrors != 0) {
@@ -228,12 +214,12 @@ public class SslError {
}
/**
- * @return A String representation of this SSL error object
- * (used mostly for debugging).
+ * Returns a string representation of this object.
+ * @return A String representation of this object.
*/
public String toString() {
return "primary error: " + getPrimaryError() +
- " certificate: " + getCertificate() +
- " on URL: " + getUrl();
+ " certificate: " + getCertificate() +
+ " on URL: " + getUrl();
}
}
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 64bba54b2cee..9dea4c43b699 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -42,6 +42,13 @@ import java.util.concurrent.atomic.AtomicInteger;
* and 4 steps, called <code>onPreExecute</code>, <code>doInBackground</code>,
* <code>onProgressUpdate</code> and <code>onPostExecute</code>.</p>
*
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about using tasks and threads, read the
+ * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
+ * Threads</a> developer guide.</p>
+ * </div>
+ *
* <h2>Usage</h2>
* <p>AsyncTask must be subclassed to be used. The subclass will override at least
* one method ({@link #doInBackground}), and most often will override a
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1d8ea123c72c..5faab3603986 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -282,6 +282,10 @@ public class Build {
* <p>Applications targeting this or a later release will get these
* new changes in behavior:</p>
* <ul>
+ * <li> For devices without a dedicated menu key, the software compatibility
+ * menu key will not be shown even on phones. By targeting Ice Cream Sandwich
+ * or later, your UI must always have its own menu UI affordance if needed,
+ * on both tablets and phones. The ActionBar will take care of this for you.
* <li> 2d drawing hardware acceleration is now turned on by default.
* You can use
* {@link android.R.attr#hardwareAccelerated android:hardwareAccelerated}
@@ -296,6 +300,12 @@ public class Build {
* will not change character within the same platform version. Applications
* that wish to blend in with the device should use a theme from the
* {@link android.R.style#Theme_DeviceDefault} family.
+ * <li> Managed cursors can now throw an exception if you directly close
+ * the cursor yourself without stopping the management of it; previously failures
+ * would be silently ignored.
+ * <li> The fadingEdge attribute on views will be ignored (fading edges is no
+ * longer a standard part of the UI). A new requiresFadingEdge attribute allows
+ * applications to still force fading edges on for special cases.
* </ul>
*/
public static final int ICE_CREAM_SANDWICH = 14;
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/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index fb119b343abd..8483b4f0cf44 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1611,9 +1611,16 @@ public final class ContactsContract {
}
/**
+ * <p>
* A sub-directory of a single contact that contains all of the constituent raw contact
* {@link ContactsContract.StreamItems} rows. This directory can be used either
* with a {@link #CONTENT_URI} or {@link #CONTENT_LOOKUP_URI}.
+ * </p>
+ * <p>
+ * Querying for social stream data requires android.permission.READ_SOCIAL_STREAM
+ * permission.
+ * </p>
+ * @hide
*/
public static final class StreamItems implements StreamItemsColumns {
/**
@@ -2669,6 +2676,14 @@ public final class ContactsContract {
* {@link ContactsContract.StreamItems} for a stand-alone table containing the
* same data.
* </p>
+ * <p>
+ * Access to the social stream through this sub-directory requires additional permissions
+ * beyond the read/write contact permissions required by the provider. Querying for
+ * social stream data requires android.permission.READ_SOCIAL_STREAM permission, and
+ * inserting or updating social stream items requires android.permission.WRITE_SOCIAL_STREAM
+ * permission.
+ * </p>
+ * @hide
*/
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
/**
@@ -2963,6 +2978,12 @@ public final class ContactsContract {
* transaction correspondingly. Insertion of more items beyond the limit will
* automatically lead to deletion of the oldest items, by {@link StreamItems#TIMESTAMP}.
* </p>
+ * <p>
+ * Access to the social stream through these URIs requires additional permissions beyond the
+ * read/write contact permissions required by the provider. Querying for social stream data
+ * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating social
+ * stream items requires android.permission.WRITE_SOCIAL_STREAM permission.
+ * </p>
* <h3>Operations</h3>
* <dl>
* <dt><b>Insert</b></dt>
@@ -3075,6 +3096,7 @@ public final class ContactsContract {
* </pre>
* </dd>
* </dl>
+ * @hide
*/
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
/**
@@ -3135,6 +3157,12 @@ public final class ContactsContract {
* directory append {@link StreamItems.StreamItemPhotos#CONTENT_DIRECTORY} to
* an individual stream item URI.
* </p>
+ * <p>
+ * Access to social stream photos requires additional permissions beyond the read/write
+ * contact permissions required by the provider. Querying for social stream photos
+ * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+ * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+ * </p>
*/
public static final class StreamItemPhotos
implements BaseColumns, StreamItemPhotosColumns {
@@ -3166,6 +3194,7 @@ public final class ContactsContract {
* Columns in the StreamItems table.
*
* @see ContactsContract.StreamItems
+ * @hide
*/
protected interface StreamItemsColumns {
/**
@@ -3312,6 +3341,12 @@ public final class ContactsContract {
* Constants for the stream_item_photos table, which contains photos associated with
* social stream updates.
* </p>
+ * <p>
+ * Access to social stream photos requires additional permissions beyond the read/write
+ * contact permissions required by the provider. Querying for social stream photos
+ * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+ * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+ * </p>
* <h3>Operations</h3>
* <dl>
* <dt><b>Insert</b></dt>
@@ -3450,6 +3485,7 @@ public final class ContactsContract {
* <pre>
* </dd>
* </dl>
+ * @hide
*/
public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns {
/**
@@ -3477,6 +3513,7 @@ public final class ContactsContract {
* Columns in the StreamItemPhotos table.
*
* @see ContactsContract.StreamItemPhotos
+ * @hide
*/
protected interface StreamItemPhotosColumns {
/**
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/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 5126e482894d..98ab31081225 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -440,6 +440,9 @@ public class TextToSpeech {
private final Context mContext;
private Connection mServiceConnection;
private OnInitListener mInitListener;
+ // Written from an unspecified application thread, read from
+ // a binder thread.
+ private volatile OnUtteranceCompletedListener mUtteranceCompletedListener;
private final Object mStartLock = new Object();
private String mRequestedEngine;
@@ -1071,20 +1074,8 @@ public class TextToSpeech {
* @return {@link #ERROR} or {@link #SUCCESS}.
*/
public int setOnUtteranceCompletedListener(final OnUtteranceCompletedListener listener) {
- return runAction(new Action<Integer>() {
- @Override
- public Integer run(ITextToSpeechService service) throws RemoteException {
- ITextToSpeechCallback.Stub callback = new ITextToSpeechCallback.Stub() {
- public void utteranceCompleted(String utteranceId) {
- if (listener != null) {
- listener.onUtteranceCompleted(utteranceId);
- }
- }
- };
- service.setCallback(getPackageName(), callback);
- return SUCCESS;
- }
- }, ERROR, "setOnUtteranceCompletedListener");
+ mUtteranceCompletedListener = listener;
+ return TextToSpeech.SUCCESS;
}
/**
@@ -1137,6 +1128,15 @@ public class TextToSpeech {
private class Connection implements ServiceConnection {
private ITextToSpeechService mService;
+ private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
+ @Override
+ public void utteranceCompleted(String utteranceId) {
+ OnUtteranceCompletedListener listener = mUtteranceCompletedListener;
+ if (listener != null) {
+ listener.onUtteranceCompleted(utteranceId);
+ }
+ }
+ };
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "Connected to " + name);
@@ -1147,7 +1147,13 @@ public class TextToSpeech {
}
mServiceConnection = this;
mService = ITextToSpeechService.Stub.asInterface(service);
- dispatchOnInit(SUCCESS);
+ try {
+ mService.setCallback(getPackageName(), mCallback);
+ dispatchOnInit(SUCCESS);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Error connecting to service, setCallback() failed");
+ dispatchOnInit(ERROR);
+ }
}
}
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index c3a2308d9df7..f82c9c4f06e8 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -76,7 +76,7 @@ extends Layout
boolean includepad,
TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
this(base, display, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR,
- spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth, Integer.MAX_VALUE);
+ spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth);
}
/**
@@ -93,7 +93,7 @@ extends Layout
int width, Alignment align, TextDirectionHeuristic textDir,
float spacingmult, float spacingadd,
boolean includepad,
- TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) {
+ TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
super((ellipsize == null)
? display
: (display instanceof Spanned)
@@ -135,8 +135,6 @@ extends Layout
mEllipsize = true;
}
- mMaxLines = maxLines;
-
// Initial state is a single line with 0 characters (0 to 0),
// with top at 0 and bottom at whatever is natural, and
// undefined ellipsis.
@@ -285,7 +283,7 @@ extends Layout
reflowed.generate(text, where, where + after,
getPaint(), getWidth(), getAlignment(), getTextDirectionHeuristic(),
getSpacingMultiplier(), getSpacingAdd(),
- false, true, mEllipsizedWidth, mEllipsizeAt, mMaxLines);
+ false, true, mEllipsizedWidth, mEllipsizeAt);
int n = reflowed.getLineCount();
// If the new layout has a blank line at the end, but it is not
@@ -490,8 +488,6 @@ extends Layout
private int mTopPadding, mBottomPadding;
- private int mMaxLines;
-
private static StaticLayout sStaticLayout = new StaticLayout(null);
private static final Object[] sLock = new Object[0];
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 7c273964fa5d..583cbe615fa4 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -139,7 +139,7 @@ public class StaticLayout extends Layout {
generate(source, bufstart, bufend, paint, outerwidth, align, textDir,
spacingmult, spacingadd, includepad, includepad,
- ellipsizedWidth, ellipsize, mMaximumVisibleLineCount);
+ ellipsizedWidth, ellipsize);
mMeasured = MeasuredText.recycle(mMeasured);
mFontMetricsInt = null;
@@ -160,7 +160,7 @@ public class StaticLayout extends Layout {
Alignment align, TextDirectionHeuristic textDir,
float spacingmult, float spacingadd,
boolean includepad, boolean trackpad,
- float ellipsizedWidth, TextUtils.TruncateAt ellipsize, int maxLines) {
+ float ellipsizedWidth, TextUtils.TruncateAt ellipsize) {
mLineCount = 0;
int v = 0;
@@ -477,13 +477,13 @@ public class StaticLayout extends Layout {
width = restWidth;
}
}
- if (mLineCount >= maxLines) {
+ if (mLineCount >= mMaximumVisibleLineCount) {
break;
}
}
}
- if (paraEnd != here && mLineCount < maxLines) {
+ if (paraEnd != here && mLineCount < mMaximumVisibleLineCount) {
if ((fitTop | fitBottom | fitDescent | fitAscent) == 0) {
paint.getFontMetricsInt(fm);
@@ -514,7 +514,7 @@ public class StaticLayout extends Layout {
}
if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) &&
- mLineCount < maxLines) {
+ mLineCount < mMaximumVisibleLineCount) {
// Log.e("text", "output last " + bufEnd);
paint.getFontMetricsInt(fm);
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..8e5aefdff0e8 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -94,20 +94,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
* their layout properties.
* </p>
*
- * <div class="special">
- * <p>For an introduction to using this class to develop your
- * application's user interface, read the Developer Guide documentation on
- * <strong><a href="{@docRoot}guide/topics/ui/index.html">User Interface</a></strong>. Special topics
- * include:
- * <br/><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout</a>
- * <br/><a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>
- * <br/><a href="{@docRoot}guide/topics/ui/layout-objects.html">Common Layout Objects</a>
- * <br/><a href="{@docRoot}guide/topics/ui/binding.html">Binding to Data with AdapterView</a>
- * <br/><a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a>
- * <br/><a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>
- * <br/><a href="{@docRoot}guide/topics/ui/custom-components.html">Building Custom Components</a>
- * <br/><a href="{@docRoot}guide/topics/ui/how-android-draws.html">How Android Draws Views</a>.
- * </p>
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For information about using this class to develop your application's user interface,
+ * read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> developer guide.
* </div>
*
* <a name="Using"></a>
@@ -1487,6 +1477,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 +3857,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 +3881,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 +3904,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 +12096,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/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 28f54aa08e7c..8c22da09c15c 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -43,7 +43,6 @@ import junit.framework.Assert;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
-import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charsets;
import java.security.PrivateKey;
@@ -472,8 +471,6 @@ class BrowserFrame extends Handler {
/**
* We have received an SSL certificate for the main top-level page.
- *
- * !!!Called from the network thread!!!
*/
void certificate(SslCertificate certificate) {
if (mIsMainFrame) {
@@ -1171,12 +1168,7 @@ class BrowserFrame extends Handler {
try {
X509Certificate cert = new X509CertImpl(certDER);
SslCertificate sslCert = new SslCertificate(cert);
- if (JniUtil.useChromiumHttpStack()) {
- sslError = SslError.SslErrorFromChromiumErrorCode(certError, sslCert,
- new URL(url).getHost());
- } else {
- sslError = new SslError(certError, cert, url);
- }
+ sslError = SslError.SslErrorFromChromiumErrorCode(certError, sslCert, url);
} catch (IOException e) {
// Can't get the certificate, not much to do.
Log.e(LOGTAG, "Can't get the certificate from WebKit, canceling");
@@ -1192,12 +1184,11 @@ class BrowserFrame extends Handler {
SslErrorHandler handler = new SslErrorHandler() {
@Override
public void proceed() {
- SslCertLookupTable.getInstance().setIsAllowed(sslError, true);
+ SslCertLookupTable.getInstance().setIsAllowed(sslError);
nativeSslCertErrorProceed(handle);
}
@Override
public void cancel() {
- SslCertLookupTable.getInstance().setIsAllowed(sslError, false);
nativeSslCertErrorCancel(handle, certError);
}
};
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/SslCertLookupTable.java b/core/java/android/webkit/SslCertLookupTable.java
index 052244f95f89..a06836cfaa68 100644
--- a/core/java/android/webkit/SslCertLookupTable.java
+++ b/core/java/android/webkit/SslCertLookupTable.java
@@ -19,10 +19,14 @@ package android.webkit;
import android.os.Bundle;
import android.net.http.SslError;
+import java.net.MalformedURLException;
+import java.net.URL;
+
/**
* Stores the user's decision of whether to allow or deny an invalid certificate.
*
- * This class is not threadsafe. It is used only on the WebCore thread.
+ * This class is not threadsafe. It is used only on the WebCore thread. Also, it
+ * is used only by the Chromium HTTP stack.
*/
final class SslCertLookupTable {
private static SslCertLookupTable sTable;
@@ -39,15 +43,33 @@ final class SslCertLookupTable {
table = new Bundle();
}
- public void setIsAllowed(SslError sslError, boolean allow) {
- table.putBoolean(sslError.toString(), allow);
+ public void setIsAllowed(SslError sslError) {
+ // TODO: We should key on just the host. See http://b/5409251.
+ String errorString = sslErrorToString(sslError);
+ if (errorString != null) {
+ table.putBoolean(errorString, true);
+ }
}
public boolean isAllowed(SslError sslError) {
- return table.getBoolean(sslError.toString());
+ // TODO: We should key on just the host. See http://b/5409251.
+ String errorString = sslErrorToString(sslError);
+ return errorString == null ? false : table.getBoolean(errorString);
}
public void clear() {
table.clear();
}
+
+ private static String sslErrorToString(SslError error) {
+ String host;
+ try {
+ host = new URL(error.getUrl()).getHost();
+ } catch(MalformedURLException e) {
+ return null;
+ }
+ return "primary error: " + error.getPrimaryError() +
+ " certificate: " + error.getCertificate() +
+ " on host: " + host;
+ }
}
diff --git a/core/java/android/webkit/SslErrorHandlerImpl.java b/core/java/android/webkit/SslErrorHandlerImpl.java
index e029e372c141..82cd3e80448a 100644
--- a/core/java/android/webkit/SslErrorHandlerImpl.java
+++ b/core/java/android/webkit/SslErrorHandlerImpl.java
@@ -16,8 +16,6 @@
package android.webkit;
-import junit.framework.Assert;
-
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
@@ -54,7 +52,7 @@ class SslErrorHandlerImpl extends SslErrorHandler {
private final SslErrorHandler mOriginHandler;
private final LoadListener mLoadListener;
- // Message id for handling the response
+ // Message id for handling the response from the client.
private static final int HANDLE_RESPONSE = 100;
@Override
@@ -130,7 +128,9 @@ class SslErrorHandlerImpl extends SslErrorHandler {
}
/**
- * Handles SSL error(s) on the way up to the user.
+ * Handles requests from the network stack about whether to proceed with a
+ * load given an SSL error(s). We may ask the client what to do, or use a
+ * cached response.
*/
/* package */ synchronized void handleSslErrorRequest(LoadListener loader) {
if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -147,8 +147,10 @@ class SslErrorHandlerImpl extends SslErrorHandler {
}
/**
- * Check the preference table for a ssl error that has already been shown
- * to the user.
+ * Check the preference table to see if we already have a 'proceed' decision
+ * from the client for this host and for an error of equal or greater
+ * severity than the supplied error. If so, instruct the loader to proceed
+ * and return true. Otherwise return false.
*/
/* package */ synchronized boolean checkSslPrefTable(LoadListener loader,
SslError error) {
@@ -156,21 +158,22 @@ class SslErrorHandlerImpl extends SslErrorHandler {
final int primary = error.getPrimaryError();
if (DebugFlags.SSL_ERROR_HANDLER) {
- Assert.assertTrue(host != null && primary != 0);
+ assert host != null;
+ assert primary != 0;
}
- if (mSslPrefTable.containsKey(host)) {
- if (primary <= mSslPrefTable.getInt(host)) {
- handleSslErrorResponse(loader, error, true);
- return true;
+ if (mSslPrefTable.containsKey(host) && primary <= mSslPrefTable.getInt(host)) {
+ if (!loader.cancelled()) {
+ loader.handleSslErrorResponse(true);
}
+ return true;
}
return false;
}
/**
* Processes queued SSL-error confirmation requests in
- * a tight loop while there is no need to ask the user.
+ * a tight loop while there is no need to ask the client.
*/
/* package */void fastProcessQueuedSslErrors() {
while (processNextLoader());
@@ -195,19 +198,18 @@ class SslErrorHandlerImpl extends SslErrorHandler {
SslError error = loader.sslError();
if (DebugFlags.SSL_ERROR_HANDLER) {
- Assert.assertNotNull(error);
+ assert error != null;
}
- // checkSslPrefTable will handle the ssl error response if the
- // answer is available. It does not remove the loader from the
- // queue.
+ // checkSslPrefTable() will instruct the loader to proceed if we
+ // have a cached 'proceed' decision. It does not remove the loader
+ // from the queue.
if (checkSslPrefTable(loader, error)) {
mLoaderQueue.remove(loader);
return true;
}
- // if we do not have information on record, ask
- // the user (display a dialog)
+ // If we can not proceed based on a cached decision, ask the client.
CallbackProxy proxy = loader.getFrame().getCallbackProxy();
proxy.onReceivedSslError(new SslErrorHandlerImpl(this, loader), error);
}
@@ -217,32 +219,31 @@ class SslErrorHandlerImpl extends SslErrorHandler {
}
/**
- * Proceed with the SSL certificate.
+ * Proceed with this load.
*/
public void proceed() {
- mOriginHandler.sendMessage(
- mOriginHandler.obtainMessage(
- HANDLE_RESPONSE, 1, 0, mLoadListener));
+ mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
+ HANDLE_RESPONSE, 1, 0, mLoadListener));
}
/**
- * Cancel this request and all pending requests for the WebView that had
- * the error.
+ * Cancel this load and all pending loads for the WebView that had the
+ * error.
*/
public void cancel() {
- mOriginHandler.sendMessage(
- mOriginHandler.obtainMessage(
- HANDLE_RESPONSE, 0, 0, mLoadListener));
+ mOriginHandler.sendMessage(mOriginHandler.obtainMessage(
+ HANDLE_RESPONSE, 0, 0, mLoadListener));
}
/**
- * Handles SSL error(s) on the way down from the user.
+ * Handles the response from the client about whether to proceed with this
+ * load. We save the response to be re-used in the future.
*/
/* package */ synchronized void handleSslErrorResponse(LoadListener loader,
SslError error, boolean proceed) {
if (DebugFlags.SSL_ERROR_HANDLER) {
- Assert.assertNotNull(loader);
- Assert.assertNotNull(error);
+ assert loader != null;
+ assert error != null;
}
if (DebugFlags.SSL_ERROR_HANDLER) {
@@ -253,16 +254,16 @@ class SslErrorHandlerImpl extends SslErrorHandler {
if (!loader.cancelled()) {
if (proceed) {
- // update the user's SSL error preference table
+ // Update the SSL error preference table
int primary = error.getPrimaryError();
String host = loader.host();
if (DebugFlags.SSL_ERROR_HANDLER) {
- Assert.assertTrue(host != null && primary != 0);
+ assert host != null;
+ assert primary != 0;
}
boolean hasKey = mSslPrefTable.containsKey(host);
- if (!hasKey ||
- primary > mSslPrefTable.getInt(host)) {
+ if (!hasKey || primary > mSslPrefTable.getInt(host)) {
mSslPrefTable.putInt(host, primary);
}
}
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/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index c37cc5223830..60b24bc1207e 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -33,6 +33,8 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.widget.ActivityChooserModel.ActivityChooserModelClient;
/**
@@ -169,6 +171,11 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
private boolean mIsAttachedToWindow;
/**
+ * String resource for formatting content description of the default target.
+ */
+ private int mDefaultActionButtonContentDescription;
+
+ /**
* Create a new instance.
*
* @param context The application environment.
@@ -259,7 +266,7 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
*
* <strong>Note:</strong> Clients would like to set this drawable
* as a clue about the action the chosen activity will perform. For
- * example, if share activity is to be chosen the drawable should
+ * example, if a share activity is to be chosen the drawable should
* give a clue that sharing is to be performed.
*
* @param drawable The drawable.
@@ -269,6 +276,21 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
}
/**
+ * Sets the content description for the button that expands the activity
+ * overflow list.
+ *
+ * description as a clue about the action performed by the button.
+ * For example, if a share activity is to be chosen the content
+ * description should be something like "Share with".
+ *
+ * @param resourceId The content description resource id.
+ */
+ public void setExpandActivityOverflowButtonContentDescription(int resourceId) {
+ CharSequence contentDescription = mContext.getString(resourceId);
+ mExpandActivityOverflowButtonImage.setContentDescription(contentDescription);
+ }
+
+ /**
* Set the provider hosting this view, if applicable.
* @hide Internal use only
*/
@@ -329,6 +351,8 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
if (mProvider != null) {
mProvider.subUiVisibilityChanged(true);
}
+ popupWindow.getListView().setContentDescription(mContext.getString(
+ R.string.activitychooserview_choose_application));
}
}
@@ -431,6 +455,20 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
}
/**
+ * Sets a content description of the default action button. This
+ * resource should be a string taking one formatting argument and
+ * will be used for formatting the content description of the button
+ * dynamically as the default target changes. For example, a resource
+ * pointing to the string "share with %1$s" will result in a content
+ * description "share with Bluetooth" for the Bluetooth activity.
+ *
+ * @param resourceId The resource id.
+ */
+ public void setDefaultActionButtonContentDescription(int resourceId) {
+ mDefaultActionButtonContentDescription = resourceId;
+ }
+
+ /**
* Gets the list popup window which is lazily initialized.
*
* @return The popup.
@@ -465,6 +503,12 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
ResolveInfo activity = mAdapter.getDefaultActivity();
PackageManager packageManager = mContext.getPackageManager();
mDefaultActivityButtonImage.setImageDrawable(activity.loadIcon(packageManager));
+ if (mDefaultActionButtonContentDescription != 0) {
+ CharSequence label = activity.loadLabel(packageManager);
+ String contentDescription = mContext.getString(
+ mDefaultActionButtonContentDescription, label);
+ mDefaultActivityButton.setContentDescription(contentDescription);
+ }
} else {
mDefaultActivityButton.setVisibility(View.GONE);
}
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/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index 36278907cea2..bb27b73fc296 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -171,6 +171,12 @@ public class ShareActionProvider extends ActionProvider {
activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
activityChooserView.setProvider(this);
+ // Set content description.
+ activityChooserView.setDefaultActionButtonContentDescription(
+ R.string.shareactionprovider_share_with_application);
+ activityChooserView.setExpandActivityOverflowButtonContentDescription(
+ R.string.shareactionprovider_share_with);
+
return activityChooserView;
}
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..f7a9dc1f6b85 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;
@@ -6253,7 +6262,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
result = new DynamicLayout(mText, mTransformed, mTextPaint, w,
alignment, mTextDir, mSpacingMult,
mSpacingAdd, mIncludePad, mInput == null ? effectiveEllipsize : null,
- ellipsisWidth, mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
+ ellipsisWidth);
} else {
if (boring == UNKNOWN_BORING) {
boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
@@ -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..d5450e4ab9bf 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,8 +116,11 @@ 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";
+ public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
+ = "lockscreen.biometricweakeverchosen";
private final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
@@ -334,17 +343,36 @@ public class LockPatternUtils {
}
/**
+ * Return true if the user has ever chosen biometric weak. This is true even if biometric
+ * weak is not current set.
+ *
+ * @return True if the user has ever chosen biometric weak.
+ */
+ public boolean isBiometricWeakEverChosen() {
+ return getBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY);
+ }
+
+ /**
* Used by device policy manager to validate the current password
* information it has.
*/
public int getActivePasswordQuality() {
int activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
- switch (getKeyguardStoredPasswordQuality()) {
+ // Note we don't want to use getKeyguardStoredPasswordQuality() because we want this to
+ // return biometric_weak if that is being used instead of the backup
+ int quality =
+ (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ switch (quality) {
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
if (isLockPatternEnabled()) {
activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
}
break;
+ case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
+ if (isBiometricWeakInstalled()) {
+ activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
+ }
+ break;
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
if (isLockPasswordEnabled()) {
activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
@@ -366,6 +394,7 @@ public class LockPatternUtils {
}
break;
}
+
return activePasswordQuality;
}
@@ -434,7 +463,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);
@@ -472,6 +501,7 @@ public class LockPatternUtils {
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
moveTempGallery();
}
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
@@ -589,6 +619,7 @@ public class LockPatternUtils {
} else {
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality));
+ setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
moveTempGallery();
}
if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
@@ -677,6 +708,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 +844,7 @@ public class LockPatternUtils {
|| backupMode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
return savedPasswordExists() && (passwordEnabled ||
- (isBiometricEnabled() && backupEnabled));
+ (usingBiometricWeak() && backupEnabled));
}
/**
@@ -824,16 +858,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/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 366b983c3923..01df48acd144 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -48,11 +48,11 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener {
private PasswordEntryKeyboard mSymbolsKeyboard;
private PasswordEntryKeyboard mSymbolsKeyboardShifted;
private PasswordEntryKeyboard mNumericKeyboard;
- private Context mContext;
- private View mTargetView;
- private KeyboardView mKeyboardView;
+ private final Context mContext;
+ private final View mTargetView;
+ private final KeyboardView mKeyboardView;
private long[] mVibratePattern;
- private Vibrator mVibrator;
+ private final Vibrator mVibrator;
public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) {
this(context, keyboardView, targetView, true);
@@ -228,7 +228,7 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener {
}
}
- private void handleBackspace() {
+ public void handleBackspace() {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
}
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/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9755f227a63f..18194ee0f298 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -263,6 +263,23 @@
android:label="@string/permlab_writeProfile"
android:description="@string/permdesc_writeProfile" />
+ <!-- Allows an application to read from the user's social stream.
+ @hide -->
+ <permission android:name="android.permission.READ_SOCIAL_STREAM"
+ android:permissionGroup="android.permission-group.PERSONAL_INFO"
+ android:protectionLevel="dangerous"
+ android:label="@string/permlab_readSocialStream"
+ android:description="@string/permdesc_readSocialStream" />
+
+ <!-- Allows an application to write (but not read) the user's
+ social stream data.
+ @hide -->
+ <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
+ android:permissionGroup="android.permission-group.PERSONAL_INFO"
+ android:protectionLevel="dangerous"
+ android:label="@string/permlab_writeSocialStream"
+ android:description="@string/permdesc_writeSocialStream" />
+
<!-- Allows an application to read the user's calendar data. -->
<permission android:name="android.permission.READ_CALENDAR"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 8bc5f34a84a6..e34822d2f7c7 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -135,7 +135,8 @@
<LinearLayout
android:orientation="horizontal"
android:layout_width="270dip"
- android:layout_gravity="center_vertical">
+ android:layout_gravity="center_vertical"
+ android:background="@drawable/lockscreen_password_field_dark">
<EditText android:id="@+id/passwordEntry"
android:layout_height="wrap_content"
@@ -148,11 +149,23 @@
android:textSize="24sp"
android:minEms="8"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:background="@drawable/lockscreen_password_field_dark"
+ android:background="@null"
android:textColor="?android:attr/textColorPrimary"
android:imeOptions="flagNoFullscreen|actionDone"
/>
+ <!-- This delete button is only visible for numeric PIN entry -->
+ <ImageButton android:id="@+id/pinDel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@android:drawable/ic_input_delete"
+ android:clickable="true"
+ android:padding="8dip"
+ android:layout_gravity="center"
+ android:background="?android:attr/selectableItemBackground"
+ android:visibility="gone"
+ />
+
<ImageView android:id="@+id/switch_ime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 2a66d7dba841..e1280ba8f213 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -95,9 +95,12 @@
/>
<!-- Password entry field -->
+ <!-- Note: the entire container is styled to look like the edit field,
+ since the backspace/IME switcher looks better inside -->
<LinearLayout
android:layout_gravity="center_vertical|fill_horizontal"
android:orientation="horizontal"
+ android:background="@drawable/lockscreen_password_field_dark"
android:layout_marginLeft="16dip"
android:layout_marginRight="16dip">
@@ -110,12 +113,24 @@
android:textStyle="normal"
android:inputType="textPassword"
android:textSize="36sp"
- android:background="@drawable/lockscreen_password_field_dark"
+ android:background="@null"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#ffffffff"
android:imeOptions="actionDone"
/>
+ <!-- This delete button is only visible for numeric PIN entry -->
+ <ImageButton android:id="@+id/pinDel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@android:drawable/ic_input_delete"
+ android:clickable="true"
+ android:padding="8dip"
+ android:layout_gravity="center_vertical"
+ android:background="?android:attr/selectableItemBackground"
+ android:visibility="gone"
+ />
+
<ImageView android:id="@+id/switch_ime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 727c6ea36d58..dbd49fbcc462 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1566,7 +1566,7 @@
<!-- The attribute that holds a Base64-encoded public key. -->
<attr name="publicKey" format="string" />
- <!-- Attributes relating to a package verifier -->
+ <!-- Attributes relating to a package verifier. -->
<declare-styleable name="AndroidManifestPackageVerifier" parent="AndroidManifest">
<!-- Specifies the Java-style package name that defines this
package verifier. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2d5d4cc8ff29..b1dc252d16dc 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -941,6 +941,19 @@
information. This means other applications can identify you and send your profile
information to others.</string>
+ <!-- Title of the read social stream permission, listed so the user can decide whether to allow the application to read information from the user's social stream. [CHAR LIMIT=30] -->
+ <string name="permlab_readSocialStream" product="default">read your social stream</string>
+ <string name="permdesc_readSocialStream" product="default">Allows the application to access
+ and sync social updates from you and your friends. Malicious apps can use this to read
+ private communications between you and your friends on social networks.</string>
+
+ <!-- Title of the write social stream permission, listed so the user can decide whether to allow the application to write information to the user's social stream. [CHAR LIMIT=30] -->
+ <string name="permlab_writeSocialStream" product="default">write to your social stream</string>
+ <string name="permdesc_writeSocialStream" product="default">Allows the application to display
+ social updates from your friends. Malicious apps can use this to pretend to be a friend
+ and trick you into revealing passwords or other confidential information.</string>
+
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCalendar">read calendar events plus confidential information</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -3182,6 +3195,16 @@
<!-- Description of the Enter button in a KeyboardView. [CHAR LIMIT=NONE] -->
<string name="keyboardview_keycode_enter">Enter</string>
+ <!-- ActivityChooserView - accessibility support -->
+ <!-- Description of the shwoing of a popup window with activities to choose from. [CHAR LIMIT=NONE] -->
+ <string name="activitychooserview_choose_application">Choose an application</string>
+
+ <!-- ShareActionProvider - accessibility support -->
+ <!-- Description of the choose target button in a ShareActionProvider (share UI). [CHAR LIMIT=NONE] -->
+ <string name="shareactionprovider_share_with">Share with</string>
+ <!-- Description of a share target (both in the list of such or the default share button) in a ShareActionProvider (share UI). [CHAR LIMIT=NONE] -->
+ <string name="shareactionprovider_share_with_application">Share with <xliff:g id="application_name" example="Bluetooth">%s</xliff:g></string>
+
<!-- Slide lock screen -->
<!-- Description of the sliding handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
@@ -3206,8 +3229,9 @@
<string name="description_target_soundon">Sound on</string>
<!-- Announce that a headset is required to hear keyboard keys while typing a password. [CHAR LIMIT=NONE] -->
- <string name="keyboard_headset_required_to_hear_password">Key. Headset required to hear
- keys while typing a password.</string>
+ <string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken aloud.</string>
+ <!-- The value of a keyboard key announced when accessibility is enabled and no headsed is used. [CHAR LIMIT=NONE] -->
+ <string name="keyboard_password_character_no_headset">Dot.</string>
<!-- Content description for the action bar "home" affordance. [CHAR LIMIT=NONE] -->
<string name="action_bar_home_description">Navigate home</string>
@@ -3306,4 +3330,4 @@
<!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
<string name="list_delimeter">", "</string>
-</resources> \ No newline at end of file
+</resources>
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/core/res/res/xml/password_kbd_numeric.xml b/core/res/res/xml/password_kbd_numeric.xml
index 2fd5aa0c7b62..560f8678bbaa 100755
--- a/core/res/res/xml/password_kbd_numeric.xml
+++ b/core/res/res/xml/password_kbd_numeric.xml
@@ -49,12 +49,10 @@
</Row>
<Row android:rowEdgeFlags="bottom">
+ <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"
+ android:keyWidth="66.66%p" android:keyEdgeFlags="left"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
- android:keyEdgeFlags="left"/>
- <Key android:codes="48" android:keyIcon="@drawable/sym_keyboard_num0_no_plus"/>
- <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
- android:iconPreview="@drawable/sym_keyboard_feedback_delete"
- android:isRepeatable="true" android:keyEdgeFlags="right"/>
+ android:keyEdgeFlags="right"/>
</Row>
</Keyboard>
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index c36685d0da73..d78d2effd4c8 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -18,6 +18,8 @@ package android.net;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
@@ -176,8 +178,63 @@ public class NetworkStatsTest extends TestCase {
assertEquals(64L, uidTag.getTotalBytes());
}
+ public void testGroupedByIfaceEmpty() throws Exception {
+ final NetworkStats uidStats = new NetworkStats(TEST_START, 3);
+ final NetworkStats grouped = uidStats.groupedByIface();
+
+ assertEquals(0, uidStats.size());
+ assertEquals(0, grouped.size());
+ }
+
+ public void testGroupedByIfaceAll() throws Exception {
+ final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
+ .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+ .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, 128L, 8L, 0L, 2L, 20L);
+ final NetworkStats grouped = uidStats.groupedByIface();
+
+ assertEquals(2, uidStats.size());
+ assertEquals(1, grouped.size());
+
+ assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 4L, 0L);
+ }
+
+ public void testGroupedByIface() throws Exception {
+ final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
+ .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L)
+ .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, 64L, 4L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, 512L, 32L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 128L, 8L, 0L, 0L, 0L);
+
+ final NetworkStats grouped = uidStats.groupedByIface();
+
+ assertEquals(6, uidStats.size());
+
+ assertEquals(2, grouped.size());
+ assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, 256L, 16L, 0L, 2L, 0L);
+ assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, 1024L, 64L, 0L, 0L, 0L);
+ }
+
+ public void testAddAllValues() {
+ final NetworkStats first = new NetworkStats(TEST_START, 5)
+ .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+
+ final NetworkStats second = new NetworkStats(TEST_START, 2)
+ .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L)
+ .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+
+ first.combineAllValues(second);
+
+ assertEquals(3, first.size());
+ assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 64L, 0L, 0L, 0L, 0L);
+ assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+ assertValues(first, 2, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, 32L, 0L, 0L, 0L, 0L);
+ }
+
private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
- int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
+ int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
final NetworkStats.Entry entry = stats.getValues(index, null);
assertEquals(iface, entry.iface);
assertEquals(uid, entry.uid);
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
deleted file mode 100644
index 1fd7bba2ef3c..000000000000
--- a/data/fonts/fonts.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- 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 only used by the layoutlib to display
- layouts in ADT.
--->
-<fonts>
- <font ttf="DroidSans">
- <name>sans-serif</name>
- <name>arial</name>
- <name>helvetica</name>
- <name>tahoma</name>
- <name>verdana</name>
- </font>
- <font ttf="DroidSerif">
- <name>serif</name>
- <name>times</name>
- <name>times new roman</name>
- <name>palatino</name>
- <name>georgia</name>
- <name>baskerville</name>
- <name>goudy</name>
- <name>fantasy</name>
- <name>cursive</name>
- <name>ITC Stone Serif</name>
- </font>
- <font ttf="DroidSansMono">
- <name>monospace</name>
- <name>courier</name>
- <name>courier new</name>
- <name>monaco</name>
- </font>
- <fallback ttf="DroidSansFallback" />
- <fallback ttf="MTLmr3m" />
-</fonts>
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
new file mode 100644
index 000000000000..8b83285af0f6
--- /dev/null
+++ b/data/sounds/notifications/ogg/Arcturus.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Capella.ogg b/data/sounds/notifications/ogg/Capella.ogg
new file mode 100755
index 000000000000..88a955d159bc
--- /dev/null
+++ b/data/sounds/notifications/ogg/Capella.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/CetiAlpha.ogg b/data/sounds/notifications/ogg/CetiAlpha.ogg
new file mode 100644
index 000000000000..cd09526335db
--- /dev/null
+++ b/data/sounds/notifications/ogg/CetiAlpha.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Polaris.ogg b/data/sounds/notifications/ogg/Polaris.ogg
new file mode 100755
index 000000000000..0f63a65bcdb0
--- /dev/null
+++ b/data/sounds/notifications/ogg/Polaris.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Procyon.ogg b/data/sounds/notifications/ogg/Procyon.ogg
new file mode 100755
index 000000000000..e5ffcdb15a2d
--- /dev/null
+++ b/data/sounds/notifications/ogg/Procyon.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Vega.ogg b/data/sounds/notifications/ogg/Vega.ogg
new file mode 100644
index 000000000000..7cdbf213625c
--- /dev/null
+++ b/data/sounds/notifications/ogg/Vega.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Acheron.ogg b/data/sounds/ringtones/ogg/Acheron.ogg
new file mode 100644
index 000000000000..67d73884648e
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Acheron.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Nasqueron.ogg b/data/sounds/ringtones/ogg/Nasqueron.ogg
new file mode 100644
index 000000000000..ae1a7258529a
--- /dev/null
+++ b/data/sounds/ringtones/ogg/Nasqueron.ogg
Binary files differ
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 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&mdash;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 &quot;I'm working
on it&quot; 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/resources-data.js b/docs/html/resources/resources-data.js
index 6c5d882908d0..d7700eecd8dc 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -408,6 +408,16 @@ var ANDROID_RESOURCES = [
}
},
{
+ tags: ['sample', 'new'],
+ path: 'samples/AndroidBeam/index.html',
+ title: {
+ en: 'Android Beam'
+ },
+ description: {
+ en: 'An example of how to use the Android Beam feature to send messages between two Android-powered devices (API level 14 or later) that support NFC.'
+ }
+ },
+ {
tags: ['sample', 'layout', 'ui'],
path: 'samples/ApiDemos/index.html',
title: {
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/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 21b8c7443916..0d5a72638686 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -319,6 +319,8 @@ private:
void initOutputFormat(const sp<MetaData> &inputFormat);
status_t initNativeWindow();
+ void initNativeWindowCrop();
+
void dumpPortStatus(OMX_U32 portIndex);
status_t configureCodec(const sp<MetaData> &meta);
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/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index bd7031927b5e..d51154d0710f 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -70,13 +70,6 @@ public:
clipRect = s->clipRect;
}
- if ((s->flags & Snapshot::kFlagClipSet) &&
- !(s->flags & Snapshot::kFlagDirtyLocalClip)) {
- mLocalClip.set(s->mLocalClip);
- } else {
- flags |= Snapshot::kFlagDirtyLocalClip;
- }
-
if (s->flags & Snapshot::kFlagFboTarget) {
flags |= Snapshot::kFlagFboTarget;
region = s->region;
@@ -106,18 +99,14 @@ public:
*/
kFlagIsFboLayer = 0x4,
/**
- * Indicates that the local clip should be recomputed.
- */
- kFlagDirtyLocalClip = 0x8,
- /**
* Indicates that this snapshot has changed the ortho matrix.
*/
- kFlagDirtyOrtho = 0x10,
+ kFlagDirtyOrtho = 0x8,
/**
* Indicates that this snapshot or an ancestor snapshot is
* an FBO layer.
*/
- kFlagFboTarget = 0x20
+ kFlagFboTarget = 0x10
};
/**
@@ -169,7 +158,7 @@ public:
}
if (clipped) {
- flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+ flags |= Snapshot::kFlagClipSet;
}
return clipped;
@@ -180,19 +169,16 @@ public:
*/
void setClip(float left, float top, float right, float bottom) {
clipRect->set(left, top, right, bottom);
- flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+ flags |= Snapshot::kFlagClipSet;
}
const Rect& getLocalClip() {
- if (flags & Snapshot::kFlagDirtyLocalClip) {
- mat4 inverse;
- inverse.loadInverse(*transform);
+ mat4 inverse;
+ inverse.loadInverse(*transform);
- mLocalClip.set(*clipRect);
- inverse.mapRect(mLocalClip);
+ mLocalClip.set(*clipRect);
+ inverse.mapRect(mLocalClip);
- flags &= ~Snapshot::kFlagDirtyLocalClip;
- }
return mLocalClip;
}
@@ -204,7 +190,7 @@ public:
void resetClip(float left, float top, float right, float bottom) {
clipRect = &mClipRectRoot;
clipRect->set(left, top, right, bottom);
- flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+ flags |= Snapshot::kFlagClipSet;
}
bool isIgnored() const {
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 0755fb7dfc03..5fd5c35168c7 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -302,7 +302,10 @@ void rsdScriptInvokeForEach(const Context *rsc,
DrvScript *drv = (DrvScript *)s->mHal.drv;
// We only support slot 0 (root) at this point in time.
rsAssert(slot == 0);
- mtls.sig = drv->mExportForEachSignatureList[slot];
+ mtls.sig = 0x1f; // temp fix for old apps, full table in slang_rs_export_foreach.cpp
+ if (drv->mExportForEachSignatureList) {
+ mtls.sig = drv->mExportForEachSignatureList[slot];
+ }
if (ain) {
mtls.dimX = ain->getType()->getDimX();
mtls.dimY = ain->getType()->getDimY();
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index ccc8a18aa673..7c34257a383d 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2351,22 +2351,6 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
mOutputPortSettingsHaveChanged = true;
- if (mNativeWindow != NULL) {
- int32_t left, top, right, bottom;
- CHECK(mOutputFormat->findRect(
- kKeyCropRect,
- &left, &top, &right, &bottom));
-
- android_native_rect_t crop;
- crop.left = left;
- crop.top = top;
- crop.right = right + 1;
- crop.bottom = bottom + 1;
-
- // We'll ignore any errors here, if the surface is
- // already invalid, we'll know soon enough.
- native_window_set_crop(mNativeWindow.get(), &crop);
- }
} else if (data2 == OMX_IndexConfigCommonScale) {
OMX_CONFIG_SCALEFACTORTYPE scale;
InitOMXParams(&scale);
@@ -4183,6 +4167,24 @@ status_t OMXCodec::initNativeWindow() {
return OK;
}
+void OMXCodec::initNativeWindowCrop() {
+ int32_t left, top, right, bottom;
+
+ CHECK(mOutputFormat->findRect(
+ kKeyCropRect,
+ &left, &top, &right, &bottom));
+
+ android_native_rect_t crop;
+ crop.left = left;
+ crop.top = top;
+ crop.right = right + 1;
+ crop.bottom = bottom + 1;
+
+ // We'll ignore any errors here, if the surface is
+ // already invalid, we'll know soon enough.
+ native_window_set_crop(mNativeWindow.get(), &crop);
+}
+
void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
mOutputFormat = new MetaData;
mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
@@ -4366,6 +4368,10 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) {
video_def->nFrameWidth - 1,
video_def->nFrameHeight - 1);
}
+
+ if (mNativeWindow != NULL) {
+ initNativeWindowCrop();
+ }
}
break;
}
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d0ece6c67eb8..830506c0bb9d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -30,7 +30,7 @@
<!-- Size of application thumbnail -->
<dimen name="status_bar_recents_thumbnail_width">164dp</dimen>
- <dimen name="status_bar_recents_thumbnail_height">164dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_height">145dp</dimen>
<!-- Size of application label text -->
<dimen name="status_bar_recents_app_label_text_size">16dip</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index ca9e2732f5d4..e3f5cdb6d335 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -60,6 +60,7 @@ import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ImageView.ScaleType;
import com.android.systemui.R;
import com.android.systemui.statusbar.StatusBar;
@@ -556,7 +557,7 @@ public class RecentsPanelView extends RelativeLayout
if (v.getTag() instanceof ViewHolder) {
ViewHolder h = (ViewHolder)v.getTag();
if (h.activityDescription == ad) {
- if (DEBUG) Log.v(TAG, "Updatating thumbnail #" + index + " in "
+ if (DEBUG) Log.v(TAG, "Updating thumbnail #" + index + " in "
+ h.activityDescription
+ ": " + ad.getThumbnail());
h.iconView.setImageDrawable(ad.getIcon());
@@ -578,6 +579,15 @@ public class RecentsPanelView extends RelativeLayout
// that this now covers, to improve scrolling speed.
// That can't be done until the anim is complete though.
h.thumbnailViewImage.setImageBitmap(thumbnail);
+
+ // scale to fill up the full width
+ Matrix scaleMatrix = new Matrix();
+ float thumbnailViewWidth = h.thumbnailViewImage.getWidth();
+ float scale = thumbnailViewWidth / thumbnail.getWidth();
+ scaleMatrix.setScale(scale, scale);
+ h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
+ h.thumbnailViewImage.setImageMatrix(scaleMatrix);
+
if (anim) {
h.thumbnailViewImage.setAnimation(AnimationUtils.loadAnimation(
mContext, R.anim.recent_appear));
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..899a7610b40c 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -231,6 +231,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
}
};
+ private TransportControlView mTransportControlView;
+
/**
* @return Whether we are stuck on the lock screen because the sim is
* missing.
@@ -516,7 +518,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
// When screen is turned on, need to bind to FaceLock service if we are using FaceLock
// But only if not dealing with a call
- if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE) {
+ final boolean transportInvisible = mTransportControlView == null ? true :
+ mTransportControlView.getVisibility() != View.VISIBLE;
+ if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
+ && transportInvisible) {
bindToFaceLock();
} else {
mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
@@ -531,7 +536,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);
@@ -804,14 +810,13 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
}
private void initializeTransportControlView(View view) {
- com.android.internal.widget.TransportControlView tcv =
- (TransportControlView) view.findViewById(R.id.transport);
- if (tcv == null) {
+ mTransportControlView = (TransportControlView) view.findViewById(R.id.transport);
+ if (mTransportControlView == null) {
if (DEBUG) Log.w(TAG, "Couldn't find transport control widget");
} else {
mUpdateMonitor.reportClockVisible(true);
- tcv.setVisibility(View.GONE); // hide tcv until we get the callback below to show it.
- tcv.setCallback(mWidgetCallback);
+ mTransportControlView.setVisibility(View.GONE); // hide until it requests being shown.
+ mTransportControlView.setCallback(mWidgetCallback);
}
}
@@ -1014,7 +1019,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 +1036,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 +1086,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 +1107,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/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 6d2f2f29fc05..ec0072c3c210 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -60,19 +60,18 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
private final KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback;
- private boolean mIsAlpha;
+ private final boolean mIsAlpha;
- private EditText mPasswordEntry;
- private LockPatternUtils mLockPatternUtils;
- private PasswordEntryKeyboardView mKeyboardView;
- private PasswordEntryKeyboardHelper mKeyboardHelper;
+ private final EditText mPasswordEntry;
+ private final LockPatternUtils mLockPatternUtils;
+ private final PasswordEntryKeyboardView mKeyboardView;
+ private final PasswordEntryKeyboardHelper mKeyboardHelper;
- private int mCreationOrientation;
- private int mCreationHardKeyboardHidden;
- private CountDownTimer mCountdownTimer;
+ private final int mCreationOrientation;
+ private final int mCreationHardKeyboardHidden;
- private KeyguardStatusViewManager mStatusViewManager;
- private boolean mUseSystemIME = true; // TODO: Make configurable
+ private final KeyguardStatusViewManager mStatusViewManager;
+ private final boolean mUseSystemIME = true; // TODO: Make configurable
private boolean mResuming; // used to prevent poking the wakelock during onResume()
// To avoid accidental lockout due to events while the device in in the pocket, ignore
@@ -119,6 +118,19 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
mKeyboardView.setVisibility(mCreationHardKeyboardHidden
== Configuration.HARDKEYBOARDHIDDEN_NO ? View.INVISIBLE : View.VISIBLE);
+
+ // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
+ // not a separate view
+ View pinDelete = findViewById(R.id.pinDel);
+ if (pinDelete != null) {
+ pinDelete.setVisibility(View.VISIBLE);
+ pinDelete.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mKeyboardHelper.handleBackspace();
+ }
+ });
+ }
}
mPasswordEntry.requestFocus();
@@ -293,7 +305,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
mPasswordEntry.setEnabled(false);
mKeyboardView.setEnabled(false);
long elapsedRealtime = SystemClock.elapsedRealtime();
- mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
+ new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
@Override
public void onTick(long millisUntilFinished) {
@@ -309,7 +321,6 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
mPasswordEntry.setEnabled(true);
mKeyboardView.setEnabled(true);
mStatusViewManager.resetStatusInfo();
- mCountdownTimer = null;
}
}.start();
}
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/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index fe49cd2bd4c8..7b8657a03f26 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -325,14 +325,16 @@ class BackupManagerService extends IBackupManager.Stub {
public boolean includeApks;
public boolean includeShared;
public boolean allApps;
+ public boolean includeSystem;
public String[] packages;
FullBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveShared,
- boolean doAllApps, String[] pkgList) {
+ boolean doAllApps, boolean doSystem, String[] pkgList) {
fd = output;
includeApks = saveApks;
includeShared = saveShared;
allApps = doAllApps;
+ includeSystem = doSystem;
packages = pkgList;
}
}
@@ -504,7 +506,7 @@ class BackupManagerService extends IBackupManager.Stub {
PerformFullBackupTask task = new PerformFullBackupTask(params.fd,
params.observer, params.includeApks,
params.includeShared, params.curPassword, params.encryptPassword,
- params.allApps, params.packages, params.latch);
+ params.allApps, params.includeSystem, params.packages, params.latch);
(new Thread(task)).start();
break;
}
@@ -2161,6 +2163,7 @@ class BackupManagerService extends IBackupManager.Stub {
boolean mIncludeApks;
boolean mIncludeShared;
boolean mAllApps;
+ final boolean mIncludeSystem;
String[] mPackages;
String mCurrentPassword;
String mEncryptPassword;
@@ -2219,13 +2222,14 @@ class BackupManagerService extends IBackupManager.Stub {
PerformFullBackupTask(ParcelFileDescriptor fd, IFullBackupRestoreObserver observer,
boolean includeApks, boolean includeShared, String curPassword,
- String encryptPassword, boolean doAllApps, String[] packages,
+ String encryptPassword, boolean doAllApps, boolean doSystem, String[] packages,
AtomicBoolean latch) {
mOutputFile = fd;
mObserver = observer;
mIncludeApks = includeApks;
mIncludeShared = includeShared;
mAllApps = doAllApps;
+ mIncludeSystem = doSystem;
mPackages = packages;
mCurrentPassword = curPassword;
// when backing up, if there is a current backup password, we require that
@@ -2245,7 +2249,7 @@ class BackupManagerService extends IBackupManager.Stub {
@Override
public void run() {
- final List<PackageInfo> packagesToBackup;
+ List<PackageInfo> packagesToBackup = new ArrayList<PackageInfo>();
Slog.i(TAG, "--- Performing full-dataset backup ---");
sendStartBackup();
@@ -2254,8 +2258,23 @@ class BackupManagerService extends IBackupManager.Stub {
if (mAllApps) {
packagesToBackup = mPackageManager.getInstalledPackages(
PackageManager.GET_SIGNATURES);
- } else {
- packagesToBackup = new ArrayList<PackageInfo>();
+ // Exclude system apps if we've been asked to do so
+ if (mIncludeSystem == false) {
+ for (int i = 0; i < packagesToBackup.size(); ) {
+ PackageInfo pkg = packagesToBackup.get(i);
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ packagesToBackup.remove(i);
+ } else {
+ i++;
+ }
+ }
+ }
+ }
+
+ // Now process the command line argument packages, if any. Note that explicitly-
+ // named system-partition packages will be included even if includeSystem was
+ // set to false.
+ if (mPackages != null) {
for (String pkgName : mPackages) {
try {
packagesToBackup.add(mPackageManager.getPackageInfo(pkgName,
@@ -2268,8 +2287,8 @@ class BackupManagerService extends IBackupManager.Stub {
// Cull any packages that have indicated that backups are not permitted.
for (int i = 0; i < packagesToBackup.size(); ) {
- PackageInfo info = packagesToBackup.get(i);
- if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
+ PackageInfo pkg = packagesToBackup.get(i);
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
packagesToBackup.remove(i);
} else {
i++;
@@ -4781,7 +4800,7 @@ class BackupManagerService extends IBackupManager.Stub {
// to the supplied file descriptor. This method is synchronous and does not return
// to the caller until the backup has been completed.
public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
- boolean doAllApps, String[] pkgList) {
+ boolean doAllApps, boolean includeSystem, String[] pkgList) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullBackup");
// Validate
@@ -4811,7 +4830,7 @@ class BackupManagerService extends IBackupManager.Stub {
Slog.i(TAG, "Beginning full backup...");
FullBackupParams params = new FullBackupParams(fd, includeApks, includeShared,
- doAllApps, pkgList);
+ doAllApps, includeSystem, pkgList);
final int token = generateToken();
synchronized (mFullConfirmations) {
mFullConfirmations.put(token, params);
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 99f6b8ef3eb5..a7eff935c99c 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -142,5 +142,5 @@ option java_package com.android.server
# ---------------------------
# NetworkStatsService.java
# ---------------------------
-51100 netstats_mobile_sample (iface_rx_bytes|2|2),(iface_tx_bytes|2|2),(iface_rx_pkts|2|1),(iface_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1)
-51101 netstats_wifi_sample (iface_rx_bytes|2|2),(iface_tx_bytes|2|2),(iface_rx_pkts|2|1),(iface_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1)
+51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
+51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index aacaa6a5a09e..f1a404a21f63 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -22,6 +22,7 @@ import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
+import static android.net.TrafficStats.UID_TETHERING;
import static android.provider.Settings.Secure.NETSTATS_ENABLED;
import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
@@ -85,11 +86,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub
@Deprecated
private final File mStatsUid;
/** Path to {@code /proc/net/dev}. */
+ @Deprecated
private final File mStatsIface;
- /** Path to {@code /proc/net/xt_qtaguid/stats}. */
- private final File mStatsXtUid;
/** Path to {@code /proc/net/xt_qtaguid/iface_stat}. */
+ @Deprecated
private final File mStatsXtIface;
+ /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */
+ private final File mStatsXtIfaceAll;
+ /** Path to {@code /proc/net/xt_qtaguid/stats}. */
+ private final File mStatsXtUid;
/**
* Name representing {@link #setGlobalAlert(long)} limit when delivered to
@@ -97,12 +102,17 @@ public class NetworkManagementService extends INetworkManagementService.Stub
*/
public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
- /** {@link #mStatsXtUid} headers. */
+ /** {@link #mStatsXtUid} and {@link #mStatsXtIfaceAll} headers. */
private static final String KEY_IDX = "idx";
private static final String KEY_IFACE = "iface";
+ private static final String KEY_ACTIVE = "active";
private static final String KEY_UID = "uid_tag_int";
private static final String KEY_COUNTER_SET = "cnt_set";
private static final String KEY_TAG_HEX = "acct_tag_hex";
+ private static final String KEY_SNAP_RX_BYTES = "snap_rx_bytes";
+ private static final String KEY_SNAP_RX_PACKETS = "snap_rx_packets";
+ private static final String KEY_SNAP_TX_BYTES = "snap_tx_bytes";
+ private static final String KEY_SNAP_TX_PACKETS = "snap_tx_packets";
private static final String KEY_RX_BYTES = "rx_bytes";
private static final String KEY_RX_PACKETS = "rx_packets";
private static final String KEY_TX_BYTES = "tx_bytes";
@@ -169,6 +179,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mStatsIface = new File(procRoot, "net/dev");
mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
mStatsXtIface = new File(procRoot, "net/xt_qtaguid/iface_stat");
+ mStatsXtIfaceAll = new File(procRoot, "net/xt_qtaguid/iface_stat_all");
if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
return;
@@ -1071,6 +1082,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
+ if (mBandwidthControlEnabled && mStatsXtIfaceAll.exists()) {
+ return getNetworkStatsSummarySingleFile();
+ } else {
+ return getNetworkStatsSummaryMultipleFiles();
+ }
+ }
+
+ @Deprecated
+ private NetworkStats getNetworkStatsSummaryMultipleFiles() {
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
final NetworkStats.Entry entry = new NetworkStats.Entry();
@@ -1155,6 +1175,61 @@ public class NetworkManagementService extends INetworkManagementService.Stub
return stats;
}
+ private NetworkStats getNetworkStatsSummarySingleFile() {
+ final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 6);
+ final NetworkStats.Entry entry = new NetworkStats.Entry();
+
+ // TODO: read directly from proc once headers are added
+ final ArrayList<String> keys = Lists.newArrayList(KEY_IFACE, KEY_ACTIVE, KEY_SNAP_RX_BYTES,
+ KEY_SNAP_RX_PACKETS, KEY_SNAP_TX_BYTES, KEY_SNAP_TX_PACKETS, KEY_RX_BYTES,
+ KEY_RX_PACKETS, KEY_TX_BYTES, KEY_TX_PACKETS);
+ final ArrayList<String> values = Lists.newArrayList();
+ final HashMap<String, String> parsed = Maps.newHashMap();
+
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(mStatsXtIfaceAll));
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ splitLine(line, values);
+ parseLine(keys, values, parsed);
+
+ entry.iface = parsed.get(KEY_IFACE);
+ entry.uid = UID_ALL;
+ entry.set = SET_DEFAULT;
+ entry.tag = TAG_NONE;
+
+ // always include snapshot values
+ entry.rxBytes = getParsedLong(parsed, KEY_SNAP_RX_BYTES);
+ entry.rxPackets = getParsedLong(parsed, KEY_SNAP_RX_PACKETS);
+ entry.txBytes = getParsedLong(parsed, KEY_SNAP_TX_BYTES);
+ entry.txPackets = getParsedLong(parsed, KEY_SNAP_TX_PACKETS);
+
+ // fold in active numbers, but only when active
+ final boolean active = getParsedInt(parsed, KEY_ACTIVE) != 0;
+ if (active) {
+ entry.rxBytes += getParsedLong(parsed, KEY_RX_BYTES);
+ entry.rxPackets += getParsedLong(parsed, KEY_RX_PACKETS);
+ entry.txBytes += getParsedLong(parsed, KEY_TX_BYTES);
+ entry.txPackets += getParsedLong(parsed, KEY_TX_PACKETS);
+ }
+
+ stats.addValues(entry);
+ }
+ } catch (NullPointerException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
+ } catch (IOException e) {
+ throw new IllegalStateException("problem parsing stats: " + e);
+ } finally {
+ IoUtils.closeQuietly(reader);
+ }
+
+ return stats;
+ }
+
@Override
public NetworkStats getNetworkStatsDetail() {
mContext.enforceCallingOrSelfPermission(
@@ -1522,7 +1597,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
try {
final NetworkStats.Entry entry = new NetworkStats.Entry();
entry.iface = ifaceIn;
- entry.uid = UID_ALL;
+ entry.uid = UID_TETHERING;
entry.set = SET_DEFAULT;
entry.tag = TAG_NONE;
entry.rxBytes = Long.parseLong(tok[3]);
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/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index aa46795b4fb9..e5f0a77974b8 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -35,7 +35,6 @@ import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.UID_REMOVED;
-import static android.net.TrafficStats.UID_TETHERING;
import static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION;
import static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY;
import static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD;
@@ -72,7 +71,6 @@ import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
-import android.net.TrafficStats;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
@@ -140,11 +138,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private static final int MSG_UPDATE_IFACES = 2;
/** Flags to control detail level of poll event. */
- private static final int FLAG_PERSIST_NETWORK = 0x10;
- private static final int FLAG_PERSIST_UID = 0x20;
+ private static final int FLAG_PERSIST_NETWORK = 0x1;
+ private static final int FLAG_PERSIST_UID = 0x2;
private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
private static final int FLAG_PERSIST_FORCE = 0x100;
+ /** Sample recent usage after each poll event. */
+ private static final boolean ENABLE_SAMPLE_AFTER_POLL = true;
+
private final Context mContext;
private final INetworkManagementService mNetworkManager;
private final IAlarmManager mAlarmManager;
@@ -188,20 +189,23 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
/** Set of currently active ifaces. */
private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
- /** Set of historical network layer stats for known networks. */
- private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkStats = Maps.newHashMap();
- /** Set of historical network layer stats for known UIDs. */
+ /** Set of historical {@code dev} stats for known networks. */
+ private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkDevStats = Maps.newHashMap();
+ /** Set of historical {@code xtables} stats for known networks. */
+ private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkXtStats = Maps.newHashMap();
+ /** Set of historical {@code xtables} stats for known UIDs. */
private HashMap<UidStatsKey, NetworkStatsHistory> mUidStats = Maps.newHashMap();
/** Flag if {@link #mUidStats} have been loaded from disk. */
private boolean mUidStatsLoaded = false;
- private NetworkStats mLastPollNetworkSnapshot;
+ private NetworkStats mLastPollNetworkDevSnapshot;
+ private NetworkStats mLastPollNetworkXtSnapshot;
private NetworkStats mLastPollUidSnapshot;
private NetworkStats mLastPollOperationsSnapshot;
- private NetworkStats mLastPollTetherSnapshot;
- private NetworkStats mLastPersistNetworkSnapshot;
+ private NetworkStats mLastPersistNetworkDevSnapshot;
+ private NetworkStats mLastPersistNetworkXtSnapshot;
private NetworkStats mLastPersistUidSnapshot;
/** Current counter sets for each UID. */
@@ -213,7 +217,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private final HandlerThread mHandlerThread;
private final Handler mHandler;
- private final AtomicFile mNetworkFile;
+ private final AtomicFile mNetworkDevFile;
+ private final AtomicFile mNetworkXtFile;
private final AtomicFile mUidFile;
public NetworkStatsService(
@@ -244,7 +249,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
- mNetworkFile = new AtomicFile(new File(systemDir, "netstats.bin"));
+ mNetworkDevFile = new AtomicFile(new File(systemDir, "netstats.bin"));
+ mNetworkXtFile = new AtomicFile(new File(systemDir, "netstats_xt.bin"));
mUidFile = new AtomicFile(new File(systemDir, "netstats_uid.bin"));
}
@@ -257,7 +263,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// read historical network stats from disk, since policy service
// might need them right away. we delay loading detailed UID stats
// until actually needed.
- readNetworkStatsLocked();
+ readNetworkDevStatsLocked();
+ readNetworkXtStatsLocked();
}
// watch for network interfaces to be claimed
@@ -306,11 +313,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mTeleManager.listen(mPhoneListener, LISTEN_NONE);
- writeNetworkStatsLocked();
+ writeNetworkDevStatsLocked();
+ writeNetworkXtStatsLocked();
if (mUidStatsLoaded) {
writeUidStatsLocked();
}
- mNetworkStats.clear();
+ mNetworkDevStats.clear();
+ mNetworkXtStats.clear();
mUidStats.clear();
mUidStatsLoaded = false;
}
@@ -355,14 +364,26 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+ return getHistoryForNetworkDev(template, fields);
+ }
+
+ private NetworkStatsHistory getHistoryForNetworkDev(NetworkTemplate template, int fields) {
+ return getHistoryForNetwork(template, fields, mNetworkDevStats);
+ }
+
+ private NetworkStatsHistory getHistoryForNetworkXt(NetworkTemplate template, int fields) {
+ return getHistoryForNetwork(template, fields, mNetworkXtStats);
+ }
+ private NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields,
+ HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
synchronized (mStatsLock) {
// combine all interfaces that match template
final NetworkStatsHistory combined = new NetworkStatsHistory(
mSettings.getNetworkBucketDuration(), estimateNetworkBuckets(), fields);
- for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
+ for (NetworkIdentitySet ident : source.keySet()) {
if (templateMatches(template, ident)) {
- final NetworkStatsHistory history = mNetworkStats.get(ident);
+ final NetworkStatsHistory history = source.get(ident);
if (history != null) {
combined.recordEntireHistory(history);
}
@@ -399,7 +420,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
@Override
public NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end) {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
+ return getSummaryForNetworkDev(template, start, end);
+ }
+
+ private NetworkStats getSummaryForNetworkDev(NetworkTemplate template, long start, long end) {
+ return getSummaryForNetwork(template, start, end, mNetworkDevStats);
+ }
+
+ private NetworkStats getSummaryForNetworkXt(NetworkTemplate template, long start, long end) {
+ return getSummaryForNetwork(template, start, end, mNetworkXtStats);
+ }
+ private NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end,
+ HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
synchronized (mStatsLock) {
// use system clock to be externally consistent
final long now = System.currentTimeMillis();
@@ -409,9 +442,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
NetworkStatsHistory.Entry historyEntry = null;
// combine total from all interfaces that match template
- for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
+ for (NetworkIdentitySet ident : source.keySet()) {
if (templateMatches(template, ident)) {
- final NetworkStatsHistory history = mNetworkStats.get(ident);
+ final NetworkStatsHistory history = source.get(ident);
historyEntry = history.getValues(start, end, now, historyEntry);
entry.iface = IFACE_ALL;
@@ -716,8 +749,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
*/
private void bootstrapStats() {
try {
- mLastPollNetworkSnapshot = mNetworkManager.getNetworkStatsSummary();
mLastPollUidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+ mLastPollNetworkDevSnapshot = mNetworkManager.getNetworkStatsSummary();
+ mLastPollNetworkXtSnapshot = computeNetworkXtSnapshotFromUid(mLastPollUidSnapshot);
mLastPollOperationsSnapshot = new NetworkStats(0L, 0);
} catch (IllegalStateException e) {
Slog.w(TAG, "problem reading network stats: " + e);
@@ -759,42 +793,56 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
: System.currentTimeMillis();
final long threshold = mSettings.getPersistThreshold();
+ final NetworkStats uidSnapshot;
+ final NetworkStats networkXtSnapshot;
+ final NetworkStats networkDevSnapshot;
try {
- // record tethering stats; persisted during normal UID cycle below
- final String[] ifacePairs = mConnManager.getTetheredIfacePairs();
+ // collect any tethering stats
+ final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
final NetworkStats tetherSnapshot = mNetworkManager.getNetworkStatsTethering(
- ifacePairs);
- performTetherPollLocked(tetherSnapshot, currentTime);
+ tetheredIfacePairs);
- // record uid stats
- final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+ // record uid stats, folding in tethering stats
+ uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
+ uidSnapshot.combineAllValues(tetherSnapshot);
performUidPollLocked(uidSnapshot, currentTime);
- // persist when enough network data has occurred
- final NetworkStats persistUidDelta = computeStatsDelta(
- mLastPersistUidSnapshot, uidSnapshot, true);
- final boolean uidPastThreshold = persistUidDelta.getTotalBytes() > threshold;
- if (persistForce || (persistUid && uidPastThreshold)) {
- writeUidStatsLocked();
- mLastPersistUidSnapshot = uidSnapshot;
- }
+ // record dev network stats
+ networkDevSnapshot = mNetworkManager.getNetworkStatsSummary();
+ performNetworkDevPollLocked(networkDevSnapshot, currentTime);
+
+ // record xt network stats
+ networkXtSnapshot = computeNetworkXtSnapshotFromUid(uidSnapshot);
+ performNetworkXtPollLocked(networkXtSnapshot, currentTime);
- // record network stats
- final NetworkStats networkSnapshot = mNetworkManager.getNetworkStatsSummary();
- performNetworkPollLocked(networkSnapshot, currentTime);
-
- // persist when enough network data has occurred
- final NetworkStats persistNetworkDelta = computeStatsDelta(
- mLastPersistNetworkSnapshot, networkSnapshot, true);
- final boolean networkPastThreshold = persistNetworkDelta.getTotalBytes() > threshold;
- if (persistForce || (persistNetwork && networkPastThreshold)) {
- writeNetworkStatsLocked();
- mLastPersistNetworkSnapshot = networkSnapshot;
- }
} catch (IllegalStateException e) {
Log.wtf(TAG, "problem reading network stats", e);
+ return;
} catch (RemoteException e) {
// ignored; service lives in system_server
+ return;
+ }
+
+ // persist when enough network data has occurred
+ final long persistNetworkDevDelta = computeStatsDelta(
+ mLastPersistNetworkDevSnapshot, networkDevSnapshot, true).getTotalBytes();
+ final long persistNetworkXtDelta = computeStatsDelta(
+ mLastPersistNetworkXtSnapshot, networkXtSnapshot, true).getTotalBytes();
+ final boolean networkOverThreshold = persistNetworkDevDelta > threshold
+ || persistNetworkXtDelta > threshold;
+ if (persistForce || (persistNetwork && networkOverThreshold)) {
+ writeNetworkDevStatsLocked();
+ writeNetworkXtStatsLocked();
+ mLastPersistNetworkDevSnapshot = networkDevSnapshot;
+ mLastPersistNetworkXtSnapshot = networkXtSnapshot;
+ }
+
+ // persist when enough uid data has occurred
+ final long persistUidDelta = computeStatsDelta(mLastPersistUidSnapshot, uidSnapshot, true)
+ .getTotalBytes();
+ if (persistForce || (persistUid && persistUidDelta > threshold)) {
+ writeUidStatsLocked();
+ mLastPersistUidSnapshot = uidSnapshot;
}
if (LOGV) {
@@ -802,8 +850,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
Slog.v(TAG, "performPollLocked() took " + duration + "ms");
}
- // sample stats after each full poll
- performSample();
+ if (ENABLE_SAMPLE_AFTER_POLL) {
+ // sample stats after each full poll
+ performSample();
+ }
// finally, dispatch updated event to any listeners
final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
@@ -812,12 +862,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
/**
- * Update {@link #mNetworkStats} historical usage.
+ * Update {@link #mNetworkDevStats} historical usage.
*/
- private void performNetworkPollLocked(NetworkStats networkSnapshot, long currentTime) {
+ private void performNetworkDevPollLocked(NetworkStats networkDevSnapshot, long currentTime) {
final HashSet<String> unknownIface = Sets.newHashSet();
- final NetworkStats delta = computeStatsDelta(mLastPollNetworkSnapshot, networkSnapshot, false);
+ final NetworkStats delta = computeStatsDelta(
+ mLastPollNetworkDevSnapshot, networkDevSnapshot, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
@@ -829,88 +880,86 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
continue;
}
- final NetworkStatsHistory history = findOrCreateNetworkStatsLocked(ident);
+ final NetworkStatsHistory history = findOrCreateNetworkDevStatsLocked(ident);
history.recordData(timeStart, currentTime, entry);
}
- mLastPollNetworkSnapshot = networkSnapshot;
+ mLastPollNetworkDevSnapshot = networkDevSnapshot;
if (LOGD && unknownIface.size() > 0) {
- Slog.w(TAG, "unknown interfaces " + unknownIface.toString() + ", ignoring those stats");
+ Slog.w(TAG, "unknown dev interfaces " + unknownIface + ", ignoring those stats");
}
}
/**
- * Update {@link #mUidStats} historical usage.
+ * Update {@link #mNetworkXtStats} historical usage.
*/
- private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
- ensureUidStatsLoadedLocked();
+ private void performNetworkXtPollLocked(NetworkStats networkXtSnapshot, long currentTime) {
+ final HashSet<String> unknownIface = Sets.newHashSet();
- final NetworkStats delta = computeStatsDelta(mLastPollUidSnapshot, uidSnapshot, false);
- final NetworkStats operationsDelta = computeStatsDelta(
- mLastPollOperationsSnapshot, mOperations, false);
+ final NetworkStats delta = computeStatsDelta(
+ mLastPollNetworkXtSnapshot, networkXtSnapshot, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
- NetworkStats.Entry operationsEntry = null;
for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);
final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
if (ident == null) {
- if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0
- || entry.txPackets > 0) {
- Log.w(TAG, "dropping UID delta from unknown iface: " + entry);
- }
+ unknownIface.add(entry.iface);
continue;
}
- // splice in operation counts since last poll
- final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.set, entry.tag);
- if (j != -1) {
- operationsEntry = operationsDelta.getValues(j, operationsEntry);
- entry.operations = operationsEntry.operations;
- }
-
- final NetworkStatsHistory history = findOrCreateUidStatsLocked(
- ident, entry.uid, entry.set, entry.tag);
+ final NetworkStatsHistory history = findOrCreateNetworkXtStatsLocked(ident);
history.recordData(timeStart, currentTime, entry);
}
- mLastPollUidSnapshot = uidSnapshot;
- mLastPollOperationsSnapshot = mOperations;
- mOperations = new NetworkStats(0L, 10);
+ mLastPollNetworkXtSnapshot = networkXtSnapshot;
+
+ if (LOGD && unknownIface.size() > 0) {
+ Slog.w(TAG, "unknown xt interfaces " + unknownIface + ", ignoring those stats");
+ }
}
/**
- * Update {@link #mUidStats} historical usage for
- * {@link TrafficStats#UID_TETHERING} based on tethering statistics.
+ * Update {@link #mUidStats} historical usage.
*/
- private void performTetherPollLocked(NetworkStats tetherSnapshot, long currentTime) {
+ private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
ensureUidStatsLoadedLocked();
- final NetworkStats delta = computeStatsDelta(
- mLastPollTetherSnapshot, tetherSnapshot, false);
+ final NetworkStats delta = computeStatsDelta(mLastPollUidSnapshot, uidSnapshot, false);
+ final NetworkStats operationsDelta = computeStatsDelta(
+ mLastPollOperationsSnapshot, mOperations, false);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
+ NetworkStats.Entry operationsEntry = null;
for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);
final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
if (ident == null) {
if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0
|| entry.txPackets > 0) {
- Log.w(TAG, "dropping tether delta from unknown iface: " + entry);
+ Log.w(TAG, "dropping UID delta from unknown iface: " + entry);
}
continue;
}
+ // splice in operation counts since last poll
+ final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.set, entry.tag);
+ if (j != -1) {
+ operationsEntry = operationsDelta.getValues(j, operationsEntry);
+ entry.operations = operationsEntry.operations;
+ }
+
final NetworkStatsHistory history = findOrCreateUidStatsLocked(
- ident, UID_TETHERING, SET_DEFAULT, TAG_NONE);
+ ident, entry.uid, entry.set, entry.tag);
history.recordData(timeStart, currentTime, entry);
}
- // normal UID poll will trim any history beyond max
- mLastPollTetherSnapshot = tetherSnapshot;
+ mLastPollUidSnapshot = uidSnapshot;
+ mLastPollOperationsSnapshot = mOperations;
+ mOperations = new NetworkStats(0L, 10);
}
/**
@@ -925,25 +974,34 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final long end = now - (now % largestBucketSize) + largestBucketSize;
final long start = end - largestBucketSize;
+ final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
+
NetworkTemplate template = null;
- NetworkStats.Entry ifaceTotal = null;
+ NetworkStats.Entry devTotal = null;
+ NetworkStats.Entry xtTotal = null;
NetworkStats.Entry uidTotal = null;
// collect mobile sample
template = buildTemplateMobileAll(getActiveSubscriberId(mContext));
- ifaceTotal = getSummaryForNetwork(template, start, end).getTotal(ifaceTotal);
+ devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+ xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
- EventLogTags.writeNetstatsMobileSample(ifaceTotal.rxBytes, ifaceTotal.rxPackets,
- ifaceTotal.txBytes, ifaceTotal.txPackets, uidTotal.rxBytes, uidTotal.rxPackets,
- uidTotal.txBytes, uidTotal.txPackets);
+ EventLogTags.writeNetstatsMobileSample(
+ devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
+ xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
+ uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
+ trustedTime);
// collect wifi sample
template = buildTemplateWifi();
- ifaceTotal = getSummaryForNetwork(template, start, end).getTotal(ifaceTotal);
+ devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+ xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
- EventLogTags.writeNetstatsWifiSample(ifaceTotal.rxBytes, ifaceTotal.rxPackets,
- ifaceTotal.txBytes, ifaceTotal.txPackets, uidTotal.rxBytes, uidTotal.rxPackets,
- uidTotal.txBytes, uidTotal.txPackets);
+ EventLogTags.writeNetstatsWifiSample(
+ devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
+ xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
+ uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
+ trustedTime);
}
/**
@@ -976,8 +1034,17 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
writeUidStatsLocked();
}
- private NetworkStatsHistory findOrCreateNetworkStatsLocked(NetworkIdentitySet ident) {
- final NetworkStatsHistory existing = mNetworkStats.get(ident);
+ private NetworkStatsHistory findOrCreateNetworkXtStatsLocked(NetworkIdentitySet ident) {
+ return findOrCreateNetworkStatsLocked(ident, mNetworkXtStats);
+ }
+
+ private NetworkStatsHistory findOrCreateNetworkDevStatsLocked(NetworkIdentitySet ident) {
+ return findOrCreateNetworkStatsLocked(ident, mNetworkDevStats);
+ }
+
+ private NetworkStatsHistory findOrCreateNetworkStatsLocked(
+ NetworkIdentitySet ident, HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
+ final NetworkStatsHistory existing = source.get(ident);
// update when no existing, or when bucket duration changed
final long bucketDuration = mSettings.getNetworkBucketDuration();
@@ -991,7 +1058,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
if (updated != null) {
- mNetworkStats.put(ident, updated);
+ source.put(ident, updated);
return updated;
} else {
return existing;
@@ -1024,15 +1091,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- private void readNetworkStatsLocked() {
- if (LOGV) Slog.v(TAG, "readNetworkStatsLocked()");
+ private void readNetworkDevStatsLocked() {
+ if (LOGV) Slog.v(TAG, "readNetworkDevStatsLocked()");
+ readNetworkStats(mNetworkDevFile, mNetworkDevStats);
+ }
+ private void readNetworkXtStatsLocked() {
+ if (LOGV) Slog.v(TAG, "readNetworkXtStatsLocked()");
+ readNetworkStats(mNetworkXtFile, mNetworkXtStats);
+ }
+
+ private static void readNetworkStats(
+ AtomicFile inputFile, HashMap<NetworkIdentitySet, NetworkStatsHistory> output) {
// clear any existing stats and read from disk
- mNetworkStats.clear();
+ output.clear();
DataInputStream in = null;
try {
- in = new DataInputStream(new BufferedInputStream(mNetworkFile.openRead()));
+ in = new DataInputStream(new BufferedInputStream(inputFile.openRead()));
// verify file magic header intact
final int magic = in.readInt();
@@ -1048,7 +1124,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
for (int i = 0; i < size; i++) {
final NetworkIdentitySet ident = new NetworkIdentitySet(in);
final NetworkStatsHistory history = new NetworkStatsHistory(in);
- mNetworkStats.put(ident, history);
+ output.put(ident, history);
}
break;
}
@@ -1138,41 +1214,50 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- private void writeNetworkStatsLocked() {
- if (LOGV) Slog.v(TAG, "writeNetworkStatsLocked()");
+ private void writeNetworkDevStatsLocked() {
+ if (LOGV) Slog.v(TAG, "writeNetworkDevStatsLocked()");
+ writeNetworkStats(mNetworkDevStats, mNetworkDevFile);
+ }
+ private void writeNetworkXtStatsLocked() {
+ if (LOGV) Slog.v(TAG, "writeNetworkXtStatsLocked()");
+ writeNetworkStats(mNetworkXtStats, mNetworkXtFile);
+ }
+
+ private void writeNetworkStats(
+ HashMap<NetworkIdentitySet, NetworkStatsHistory> input, AtomicFile outputFile) {
// TODO: consider duplicating stats and releasing lock while writing
// trim any history beyond max
if (mTime.hasCache()) {
final long currentTime = mTime.currentTimeMillis();
final long maxHistory = mSettings.getNetworkMaxHistory();
- for (NetworkStatsHistory history : mNetworkStats.values()) {
+ for (NetworkStatsHistory history : input.values()) {
history.removeBucketsBefore(currentTime - maxHistory);
}
}
FileOutputStream fos = null;
try {
- fos = mNetworkFile.startWrite();
+ fos = outputFile.startWrite();
final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
out.writeInt(FILE_MAGIC);
out.writeInt(VERSION_NETWORK_INIT);
- out.writeInt(mNetworkStats.size());
- for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
- final NetworkStatsHistory history = mNetworkStats.get(ident);
+ out.writeInt(input.size());
+ for (NetworkIdentitySet ident : input.keySet()) {
+ final NetworkStatsHistory history = input.get(ident);
ident.writeToStream(out);
history.writeToStream(out);
}
out.flush();
- mNetworkFile.finishWrite(fos);
+ outputFile.finishWrite(fos);
} catch (IOException e) {
Log.wtf(TAG, "problem writing stats", e);
if (fos != null) {
- mNetworkFile.failWrite(fos);
+ outputFile.failWrite(fos);
}
}
}
@@ -1280,9 +1365,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
pw.print(" ident="); pw.println(ident.toString());
}
- pw.println("Known historical stats:");
- for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
- final NetworkStatsHistory history = mNetworkStats.get(ident);
+ pw.println("Known historical dev stats:");
+ for (NetworkIdentitySet ident : mNetworkDevStats.keySet()) {
+ final NetworkStatsHistory history = mNetworkDevStats.get(ident);
+ pw.print(" ident="); pw.println(ident.toString());
+ history.dump(" ", pw, fullHistory);
+ }
+
+ pw.println("Known historical xt stats:");
+ for (NetworkIdentitySet ident : mNetworkXtStats.keySet()) {
+ final NetworkStatsHistory history = mNetworkXtStats.get(ident);
pw.print(" ident="); pw.println(ident.toString());
history.dump(" ", pw, fullHistory);
}
@@ -1333,10 +1425,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final List<ApplicationInfo> installedApps = mContext
.getPackageManager().getInstalledApplications(0);
- mNetworkStats.clear();
+ mNetworkDevStats.clear();
+ mNetworkXtStats.clear();
mUidStats.clear();
for (NetworkIdentitySet ident : mActiveIfaces.values()) {
- findOrCreateNetworkStatsLocked(ident).generateRandom(NET_START, NET_END, NET_RX_BYTES,
+ findOrCreateNetworkDevStatsLocked(ident).generateRandom(NET_START, NET_END,
+ NET_RX_BYTES, NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
+ findOrCreateNetworkXtStatsLocked(ident).generateRandom(NET_START, NET_END, NET_RX_BYTES,
NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
for (ApplicationInfo info : installedApps) {
@@ -1369,6 +1464,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
+ private static NetworkStats computeNetworkXtSnapshotFromUid(NetworkStats uidSnapshot) {
+ return uidSnapshot.groupedByIface();
+ }
+
private int estimateNetworkBuckets() {
return (int) (mSettings.getNetworkMaxHistory() / mSettings.getNetworkBucketDuration());
}
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/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 3ea9e817a1d8..8e98ec4da19d 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5704,6 +5704,7 @@ public class WindowManagerService extends IWindowManager.Stub
Configuration computeNewConfigurationLocked() {
Configuration config = new Configuration();
+ config.fontScale = 0;
if (!computeNewConfigurationLocked(config)) {
return null;
}
@@ -9002,8 +9003,8 @@ public class WindowManagerService extends IWindowManager.Stub
mScreenRotationAnimation = null;
}
updateRotation = true;
- Surface.unfreezeDisplay(0);
}
+ Surface.unfreezeDisplay(0);
mInputMonitor.thawInputDispatchingLw();
diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_iface_typical b/services/tests/servicestests/res/raw/xt_qtaguid_iface_typical
new file mode 100644
index 000000000000..efa4cd5d6917
--- /dev/null
+++ b/services/tests/servicestests/res/raw/xt_qtaguid_iface_typical
@@ -0,0 +1,6 @@
+rmnet3 1 0 0 0 0 20822 501 1149991 815
+rmnet2 1 0 0 0 0 1594 15 1313 15
+rmnet1 1 0 0 0 0 207398 458 166918 565
+rmnet0 1 0 0 0 0 2112 24 700 10
+test1 1 1 2 3 4 5 6 7 8
+test2 0 1 2 3 4 5 6 7 8
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index ab1597c6745d..40640e0ac501 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -159,6 +159,16 @@ public class NetworkManagementServiceTest extends AndroidTestCase {
assertStatsEntry(stats, "rmnet0", 1000, SET_FOREGROUND, 0, 26033L, 30L, 1401L, 26L);
}
+ public void testNetworkStatsSingle() throws Exception {
+ stageFile(R.raw.xt_qtaguid_iface_typical, new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
+
+ final NetworkStats stats = mService.getNetworkStatsSummary();
+ assertEquals(6, stats.size());
+ assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 2112L, 24L, 700L, 10L);
+ assertStatsEntry(stats, "test1", UID_ALL, SET_DEFAULT, TAG_NONE, 6L, 8L, 10L, 12L);
+ assertStatsEntry(stats, "test2", UID_ALL, SET_DEFAULT, TAG_NONE, 1L, 2L, 3L, 4L);
+ }
+
/**
* Copy a {@link Resources#openRawResource(int)} into {@link File} for
* testing purposes.
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 2ead254af18c..f7dff2358a80 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -32,6 +32,7 @@ import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.UID_REMOVED;
+import static android.net.TrafficStats.UID_TETHERING;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
@@ -179,6 +180,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -232,6 +234,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -327,6 +330,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -378,6 +382,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -459,6 +464,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -518,6 +524,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildMobile3gState(IMSI_1));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -585,6 +592,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -648,6 +656,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectNetworkState(buildWifiState());
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
@@ -705,6 +714,42 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
verifyAndReset();
}
+ public void testTethering() throws Exception {
+ // pretend first mobile network comes online
+ expectCurrentTime();
+ expectDefaultSettings();
+ expectNetworkState(buildMobile3gState(IMSI_1));
+ expectNetworkStatsSummary(buildEmptyStats());
+ expectNetworkStatsUidDetail(buildEmptyStats());
+ expectNetworkStatsPoll();
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
+ verifyAndReset();
+
+ // create some tethering traffic
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ expectCurrentTime();
+ expectDefaultSettings();
+ expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
+ expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L));
+ final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
+ expectNetworkStatsPoll(tetherIfacePairs, new NetworkStats(getElapsedRealtime(), 1)
+ .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+
+ // verify service recorded history
+ assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+ assertUidTotal(sTemplateImsi1, UID_RED, 128L, 2L, 128L, 2L, 0);
+ assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
+ verifyAndReset();
+
+ }
+
private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
long txBytes, long txPackets, int operations) {
final NetworkStatsHistory history = mService.getHistoryForNetwork(template, FIELD_ALL);
@@ -774,9 +819,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private void expectNetworkStatsPoll() throws Exception {
+ expectNetworkStatsPoll(new String[0], new NetworkStats(getElapsedRealtime(), 0));
+ }
+
+ private void expectNetworkStatsPoll(String[] tetherIfacePairs, NetworkStats tetherStats)
+ throws Exception {
mNetManager.setGlobalAlert(anyLong());
expectLastCall().anyTimes();
- expect(mConnManager.getTetheredIfacePairs()).andReturn(null).anyTimes();
+ expect(mConnManager.getTetheredIfacePairs()).andReturn(tetherIfacePairs).anyTimes();
+ expect(mNetManager.getNetworkStatsTethering(eq(tetherIfacePairs)))
+ .andReturn(tetherStats).anyTimes();
}
private void assertStatsFilesExist(boolean exist) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index e60a61c9fd97..1523823029c9 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -1166,7 +1166,7 @@ public class Paint_Delegate {
if (mTextScaleX != 1.0 || mTextSkewX != 0) {
// TODO: support skew
info.mFont = info.mFont.deriveFont(new AffineTransform(
- mTextScaleX, mTextSkewX, 0, 0, 1, 0));
+ mTextScaleX, mTextSkewX, 0, 1, 0, 0));
}
info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 0f084f7d7fc7..2414d705be8a 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -25,8 +25,8 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.content.res.AssetManager;
import java.awt.Font;
+import java.io.File;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
/**
@@ -44,13 +44,14 @@ import java.util.List;
*/
public final class Typeface_Delegate {
+ private static final String SYSTEM_FONTS = "/system/fonts/";
+
// ---- delegate manager ----
private static final DelegateManager<Typeface_Delegate> sManager =
new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
// ---- delegate helper data ----
private static final String DEFAULT_FAMILY = "sans-serif";
- private static final int[] STYLE_BUFFER = new int[1];
private static FontLoader sFontLoader;
private static final List<Typeface_Delegate> sPostInitDelegate =
@@ -145,9 +146,31 @@ public final class Typeface_Delegate {
@LayoutlibDelegate
/*package*/ static synchronized int nativeCreateFromFile(String path) {
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Typeface.createFromFile() is not supported.", null /*throwable*/, null /*data*/);
- return 0;
+ if (path.startsWith(SYSTEM_FONTS) ) {
+ String relativePath = path.substring(SYSTEM_FONTS.length());
+ File f = new File(sFontLoader.getOsFontsLocation(), relativePath);
+
+ try {
+ Font font = Font.createFont(Font.TRUETYPE_FONT, f);
+ if (font != null) {
+ Typeface_Delegate newDelegate = new Typeface_Delegate(font);
+ return sManager.addNewDelegate(newDelegate);
+ }
+ } catch (Exception e) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+ String.format("Unable to load font %1$s", relativePath),
+ null /*throwable*/, null /*data*/);
+ }
+ } else {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "Typeface.createFromFile() can only work with platform fonts located in " +
+ SYSTEM_FONTS,
+ null /*throwable*/, null /*data*/);
+ }
+
+
+ // return a copy of the base font
+ return nativeCreate(null, 0);
}
@LayoutlibDelegate
@@ -177,15 +200,17 @@ public final class Typeface_Delegate {
mStyle = style;
}
+ private Typeface_Delegate(Font font) {
+ mFamily = font.getFamily();
+ mStyle = Typeface.NORMAL;
+
+ mFonts = sFontLoader.getFallbackFonts(mStyle);
+
+ // insert the font glyph first.
+ mFonts.add(0, font);
+ }
+
private void init() {
- STYLE_BUFFER[0] = mStyle;
- Font font = sFontLoader.getFont(mFamily, STYLE_BUFFER);
- if (font != null) {
- List<Font> list = new ArrayList<Font>();
- list.add(font);
- list.addAll(sFontLoader.getFallBackFonts());
- mFonts = Collections.unmodifiableList(list);
- mStyle = STYLE_BUFFER[0];
- }
+ mFonts = sFontLoader.getFont(mFamily, mStyle);
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
index f62fad298bdd..081ce67c7950 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
@@ -23,17 +23,13 @@ import org.xml.sax.helpers.DefaultHandler;
import android.graphics.Typeface;
import java.awt.Font;
-import java.awt.FontFormatException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
@@ -47,49 +43,55 @@ import javax.xml.parsers.SAXParserFactory;
* fonts.xml file located alongside the ttf files.
*/
public final class FontLoader {
- private static final String FONTS_DEFINITIONS = "fonts.xml";
+ private static final String FONTS_SYSTEM = "system_fonts.xml";
+ private static final String FONTS_VENDOR = "vendor_fonts.xml";
+ private static final String FONTS_FALLBACK = "fallback_fonts.xml";
- private static final String NODE_FONTS = "fonts";
- private static final String NODE_FONT = "font";
+ private static final String NODE_FAMILYSET = "familyset";
+ private static final String NODE_FAMILY = "family";
private static final String NODE_NAME = "name";
- private static final String NODE_FALLBACK = "fallback";
-
- private static final String ATTR_TTF = "ttf";
-
- private static final String FONT_EXT = ".ttf";
-
- private static final String[] FONT_STYLE_DEFAULT = { "", "-Regular" };
- private static final String[] FONT_STYLE_BOLD = { "-Bold" };
- private static final String[] FONT_STYLE_ITALIC = { "-Italic" };
- private static final String[] FONT_STYLE_BOLDITALIC = { "-BoldItalic" };
-
- // list of font style, in the order matching the Typeface Font style
- private static final String[][] FONT_STYLES = {
- FONT_STYLE_DEFAULT,
- FONT_STYLE_BOLD,
- FONT_STYLE_ITALIC,
- FONT_STYLE_BOLDITALIC
+ private static final String NODE_FILE = "file";
+
+ private static final String FONT_SUFFIX_NONE = ".ttf";
+ private static final String FONT_SUFFIX_REGULAR = "-Regular.ttf";
+ private static final String FONT_SUFFIX_BOLD = "-Bold.ttf";
+ private static final String FONT_SUFFIX_ITALIC = "-Italic.ttf";
+ private static final String FONT_SUFFIX_BOLDITALIC = "-BoldItalic.ttf";
+
+ // This must match the values of Typeface styles so that we can use them for indices in this
+ // array.
+ private static final int[] AWT_STYLES = new int[] {
+ Font.PLAIN,
+ Font.BOLD,
+ Font.ITALIC,
+ Font.BOLD | Font.ITALIC
+ };
+ private static int[] DERIVE_BOLD_ITALIC = new int[] {
+ Typeface.ITALIC, Typeface.BOLD, Typeface.NORMAL
};
+ private static int[] DERIVE_ITALIC = new int[] { Typeface.NORMAL };
+ private static int[] DERIVE_BOLD = new int[] { Typeface.NORMAL };
- private final Map<String, String> mFamilyToTtf = new HashMap<String, String>();
- private final Map<String, Map<Integer, Font>> mTtfToFontMap =
- new HashMap<String, Map<Integer, Font>>();
+ private static final List<FontInfo> mMainFonts = new ArrayList<FontInfo>();
+ private static final List<FontInfo> mFallbackFonts = new ArrayList<FontInfo>();
- private List<Font> mFallBackFonts = null;
+ private final String mOsFontsLocation;
public static FontLoader create(String fontOsLocation) {
try {
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
- SAXParser parser = parserFactory.newSAXParser();
- File f = new File(fontOsLocation + File.separator + FONTS_DEFINITIONS);
+ // parse the system fonts
+ FontHandler handler = parseFontFile(parserFactory, fontOsLocation, FONTS_SYSTEM);
+ List<FontInfo> systemFonts = handler.getFontList();
- FontDefinitionParser definitionParser = new FontDefinitionParser(
- fontOsLocation + File.separator);
- parser.parse(new FileInputStream(f), definitionParser);
- return definitionParser.getFontLoader();
+ // parse the fallback fonts
+ handler = parseFontFile(parserFactory, fontOsLocation, FONTS_FALLBACK);
+ List<FontInfo> fallbackFonts = handler.getFontList();
+
+ return new FontLoader(fontOsLocation, systemFonts, fallbackFonts);
} catch (ParserConfigurationException e) {
// return null below
} catch (SAXException e) {
@@ -103,35 +105,29 @@ public final class FontLoader {
return null;
}
- private FontLoader(List<FontInfo> fontList, List<String> fallBackList) {
- for (FontInfo info : fontList) {
- for (String family : info.families) {
- mFamilyToTtf.put(family, info.ttf);
- }
- }
+ private static FontHandler parseFontFile(SAXParserFactory parserFactory,
+ String fontOsLocation, String fontFileName)
+ throws ParserConfigurationException, SAXException, IOException, FileNotFoundException {
- ArrayList<Font> list = new ArrayList<Font>();
- for (String path : fallBackList) {
- File f = new File(path + FONT_EXT);
- if (f.isFile()) {
- try {
- Font font = Font.createFont(Font.TRUETYPE_FONT, f);
- if (font != null) {
- list.add(font);
- }
- } catch (FontFormatException e) {
- // skip this font name
- } catch (IOException e) {
- // skip this font name
- }
- }
- }
+ SAXParser parser = parserFactory.newSAXParser();
+ File f = new File(fontOsLocation, fontFileName);
- mFallBackFonts = Collections.unmodifiableList(list);
+ FontHandler definitionParser = new FontHandler(
+ fontOsLocation + File.separator);
+ parser.parse(new FileInputStream(f), definitionParser);
+ return definitionParser;
}
- public List<Font> getFallBackFonts() {
- return mFallBackFonts;
+ private FontLoader(String fontOsLocation,
+ List<FontInfo> fontList, List<FontInfo> fallBackList) {
+ mOsFontsLocation = fontOsLocation;
+ mMainFonts.addAll(fontList);
+ mFallbackFonts.addAll(fallBackList);
+ }
+
+
+ public String getOsFontsLocation() {
+ return mOsFontsLocation;
}
/**
@@ -143,96 +139,43 @@ public final class FontLoader {
* the method returns.
* @return the font object or null if no match could be found.
*/
- public synchronized Font getFont(String family, int[] style) {
- if (family == null) {
- return null;
- }
+ public synchronized List<Font> getFont(String family, int style) {
+ List<Font> result = new ArrayList<Font>();
- // get the ttf name from the family
- String ttf = mFamilyToTtf.get(family);
-
- if (ttf == null) {
- return null;
- }
-
- // get the font from the ttf
- Map<Integer, Font> styleMap = mTtfToFontMap.get(ttf);
-
- if (styleMap == null) {
- styleMap = new HashMap<Integer, Font>();
- mTtfToFontMap.put(ttf, styleMap);
+ if (family == null) {
+ return result;
}
- Font f = styleMap.get(style[0]);
-
- if (f != null) {
- return f;
- }
- // if it doesn't exist, we create it, and we can't, we try with a simpler style
- switch (style[0]) {
- case Typeface.NORMAL:
- f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
- break;
- case Typeface.BOLD:
- case Typeface.ITALIC:
- f = getFont(ttf, FONT_STYLES[style[0]]);
- if (f == null) {
- f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
- style[0] = Typeface.NORMAL;
- }
- break;
- case Typeface.BOLD_ITALIC:
- f = getFont(ttf, FONT_STYLES[style[0]]);
- if (f == null) {
- f = getFont(ttf, FONT_STYLES[Typeface.BOLD]);
- if (f != null) {
- style[0] = Typeface.BOLD;
- } else {
- f = getFont(ttf, FONT_STYLES[Typeface.ITALIC]);
- if (f != null) {
- style[0] = Typeface.ITALIC;
- } else {
- f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
- style[0] = Typeface.NORMAL;
- }
- }
- }
+ // get the font objects from the main list based on family.
+ for (FontInfo info : mMainFonts) {
+ if (info.families.contains(family)) {
+ result.add(info.font[style]);
break;
+ }
}
- if (f != null) {
- styleMap.put(style[0], f);
- return f;
+ // add all the fallback fonts for the given style
+ for (FontInfo info : mFallbackFonts) {
+ result.add(info.font[style]);
}
- return null;
+ return result;
}
- private Font getFont(String ttf, String[] fontFileSuffix) {
- for (String suffix : fontFileSuffix) {
- String name = ttf + suffix + FONT_EXT;
- File f = new File(name);
- if (f.isFile()) {
- try {
- Font font = Font.createFont(Font.TRUETYPE_FONT, f);
- if (font != null) {
- return font;
- }
- } catch (FontFormatException e) {
- // skip this font name
- } catch (IOException e) {
- // skip this font name
- }
- }
+ public synchronized List<Font> getFallbackFonts(int style) {
+ List<Font> result = new ArrayList<Font>();
+ // add all the fallback fonts
+ for (FontInfo info : mFallbackFonts) {
+ result.add(info.font[style]);
}
-
- return null;
+ return result;
}
+
private final static class FontInfo {
- String ttf;
+ final Font[] font = new Font[4]; // Matches the 4 type-face styles.
final Set<String> families;
FontInfo() {
@@ -240,21 +183,20 @@ public final class FontLoader {
}
}
- private final static class FontDefinitionParser extends DefaultHandler {
+ private final static class FontHandler extends DefaultHandler {
private final String mOsFontsLocation;
private FontInfo mFontInfo = null;
private final StringBuilder mBuilder = new StringBuilder();
- private List<FontInfo> mFontList;
- private List<String> mFallBackList;
+ private List<FontInfo> mFontList = new ArrayList<FontInfo>();
- private FontDefinitionParser(String osFontsLocation) {
+ private FontHandler(String osFontsLocation) {
super();
mOsFontsLocation = osFontsLocation;
}
- FontLoader getFontLoader() {
- return new FontLoader(mFontList, mFallBackList);
+ public List<FontInfo> getFontList() {
+ return mFontList;
}
/* (non-Javadoc)
@@ -263,26 +205,11 @@ public final class FontLoader {
@Override
public void startElement(String uri, String localName, String name, Attributes attributes)
throws SAXException {
- if (NODE_FONTS.equals(localName)) {
+ if (NODE_FAMILYSET.equals(localName)) {
mFontList = new ArrayList<FontInfo>();
- mFallBackList = new ArrayList<String>();
- } else if (NODE_FONT.equals(localName)) {
+ } else if (NODE_FAMILY.equals(localName)) {
if (mFontList != null) {
- String ttf = attributes.getValue(ATTR_TTF);
- if (ttf != null) {
- mFontInfo = new FontInfo();
- mFontInfo.ttf = mOsFontsLocation + ttf;
- mFontList.add(mFontInfo);
- }
- }
- } else if (NODE_NAME.equals(localName)) {
- // do nothing, we'll handle the name in the endElement
- } else if (NODE_FALLBACK.equals(localName)) {
- if (mFallBackList != null) {
- String ttf = attributes.getValue(ATTR_TTF);
- if (ttf != null) {
- mFallBackList.add(mOsFontsLocation + ttf);
- }
+ mFontInfo = new FontInfo();
}
}
@@ -304,19 +231,78 @@ public final class FontLoader {
*/
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
- if (NODE_FONTS.equals(localName)) {
- // top level, do nothing
- } else if (NODE_FONT.equals(localName)) {
- mFontInfo = null;
+ if (NODE_FAMILY.equals(localName)) {
+ if (mFontInfo != null) {
+ // if has a normal font file, add to the list
+ if (mFontInfo.font[Typeface.NORMAL] != null) {
+ mFontList.add(mFontInfo);
+
+ // create missing font styles, order is important.
+ if (mFontInfo.font[Typeface.BOLD_ITALIC] == null) {
+ computeDerivedFont(Typeface.BOLD_ITALIC, DERIVE_BOLD_ITALIC);
+ }
+ if (mFontInfo.font[Typeface.ITALIC] == null) {
+ computeDerivedFont(Typeface.ITALIC, DERIVE_ITALIC);
+ }
+ if (mFontInfo.font[Typeface.BOLD] == null) {
+ computeDerivedFont(Typeface.BOLD, DERIVE_BOLD);
+ }
+ }
+
+ mFontInfo = null;
+ }
} else if (NODE_NAME.equals(localName)) {
// handle a new name for an existing Font Info
if (mFontInfo != null) {
String family = trimXmlWhitespaces(mBuilder.toString());
mFontInfo.families.add(family);
}
- } else if (NODE_FALLBACK.equals(localName)) {
- // nothing to do here.
+ } else if (NODE_FILE.equals(localName)) {
+ // handle a new file for an existing Font Info
+ if (mFontInfo != null) {
+ String fileName = trimXmlWhitespaces(mBuilder.toString());
+ Font font = getFont(fileName);
+ if (font != null) {
+ if (fileName.endsWith(FONT_SUFFIX_REGULAR)) {
+ mFontInfo.font[Typeface.NORMAL] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_BOLD)) {
+ mFontInfo.font[Typeface.BOLD] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_ITALIC)) {
+ mFontInfo.font[Typeface.ITALIC] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_BOLDITALIC)) {
+ mFontInfo.font[Typeface.BOLD_ITALIC] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_NONE)) {
+ mFontInfo.font[Typeface.NORMAL] = font;
+ }
+ }
+ }
+ }
+ }
+
+ private Font getFont(String fileName) {
+ try {
+ File file = new File(mOsFontsLocation, fileName);
+ if (file.exists()) {
+ return Font.createFont(Font.TRUETYPE_FONT, file);
+ }
+ } catch (Exception e) {
+
}
+
+ return null;
+ }
+
+ private void computeDerivedFont( int toCompute, int[] basedOnList) {
+ for (int basedOn : basedOnList) {
+ if (mFontInfo.font[basedOn] != null) {
+ mFontInfo.font[toCompute] =
+ mFontInfo.font[basedOn].deriveFont(AWT_STYLES[toCompute]);
+ return;
+ }
+ }
+
+ // we really shouldn't stop there. This means we don't have a NORMAL font...
+ assert false;
}
private String trimXmlWhitespaces(String value) {
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..1e45f684d459 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,13 +2590,22 @@ 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 WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
+ StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+ SupplicantState state = stateChangeResult.state;
+ // A WEXT bug means that we can be back to driver started state
+ // unexpectedly
+ if (SupplicantState.isDriverActive(state)) {
+ transitionTo(mDriverStartedState);
+ }
+ break;
case CMD_START_DRIVER:
mWakeLock.acquire();
WifiNative.startDriverCommand();
@@ -2607,12 +2623,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 +2660,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:
@@ -2660,8 +2676,18 @@ public class WifiStateMachine extends StateMachine {
sendErrorBroadcast(WifiManager.WPS_OVERLAP_ERROR);
break;
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
- handleSupplicantStateChange(message);
- break;
+ SupplicantState state = handleSupplicantStateChange(message);
+ // Due to a WEXT bug, during the time of driver start/stop
+ // we can go into a driver stopped state in an unexpected way.
+ // The sequence eventually puts interface
+ // up and we should be back to a connected state
+ if (!SupplicantState.isDriverActive(state)) {
+ if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
+ handleNetworkDisconnect();
+ }
+ transitionTo(mDriverStoppedState);
+ }
+ break;
/* Do a redundant disconnect without transition */
case CMD_DISCONNECT:
WifiNative.disconnectCommand();
@@ -2696,7 +2722,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 +2736,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 +2757,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 +2773,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 +2798,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 +2882,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 +2891,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 +2947,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 +3003,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 +3055,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 +3082,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 +3145,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 +3165,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 +3184,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 +3194,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 +3205,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 +3245,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 +3268,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 +3294,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 +3302,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 +3337,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 +3353,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);
+ }
}