From 1163f69aac0e72ea3274c2516caa540accd418ca Mon Sep 17 00:00:00 2001 From: Jack Palevich Date: Thu, 27 Oct 2011 05:45:45 -0700 Subject: [PATCH 1/4] Fix activities that want to handle screen size and orientation changes themselves. In API level 13 the android:configChanges property was changed incompatably. In API level 12 and below, an activity that wanted to handle screen size and orientation changes could achieve that by specifying android:configChanges="orientation" Starting with API level 13 the activity must specify android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize" This change updates all the activities in ApiDemos that want to handle screen size and orientation changes themselves. Fixes b/5522551 ApiDemos OpenGL ES rotation-without-restarting-Activity broken for API levels 13+ Change-Id: Ibc8b2b77eab9be279b56c026d76787d7185c62c9 --- samples/ApiDemos/AndroidManifest.xml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index 2449e062e..fd591079c 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -2137,7 +2137,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2161,7 +2161,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2171,7 +2171,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2182,7 +2182,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2192,7 +2192,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2202,7 +2202,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2211,7 +2211,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2221,7 +2221,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2231,7 +2231,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2241,7 +2241,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2251,7 +2251,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2261,7 +2261,7 @@ + android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"> @@ -2482,7 +2482,7 @@ + android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|smallestScreenSize"> From 96c0210eb57e60f03c23a8e504782a8ba4b9edfe Mon Sep 17 00:00:00 2001 From: Alexander Lucas Date: Thu, 27 Oct 2011 15:23:41 -0700 Subject: [PATCH 2/4] Adding ICS Accessibility Features to ApiDemos app. Change-Id: I37485821a77fed483308434e7b1d407642379d8c --- samples/ApiDemos/AndroidManifest.xml | 25 ++- samples/ApiDemos/_index.html | 3 + samples/ApiDemos/res/layout/tasklist_main.xml | 28 +++ samples/ApiDemos/res/layout/tasklist_row.xml | 34 ++++ samples/ApiDemos/res/values/strings.xml | 16 +- samples/ApiDemos/res/xml/taskbackconfig.xml | 25 +++ .../apis/accessibility/TaskBackService.java | 160 ++++++++++++++++++ .../apis/accessibility/TaskListActivity.java | 42 +++++ .../apis/accessibility/TaskListView.java | 119 +++++++++++++ .../android/apis/accessibility/_index.html | 9 + 10 files changed, 457 insertions(+), 4 deletions(-) create mode 100644 samples/ApiDemos/res/layout/tasklist_main.xml create mode 100644 samples/ApiDemos/res/layout/tasklist_row.xml create mode 100644 samples/ApiDemos/res/xml/taskbackconfig.xml create mode 100644 samples/ApiDemos/src/com/example/android/apis/accessibility/TaskBackService.java create mode 100644 samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListActivity.java create mode 100644 samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListView.java create mode 100644 samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index fd591079c..064d05887 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -36,7 +36,7 @@ - + @@ -242,7 +242,7 @@ - + + + + + + + + + + + + + + + + @@ -2237,7 +2256,7 @@ - +
  • Stylus and hover support
  • Switch widget
  • +
  • Window + Querying Accessibility Service
  • diff --git a/samples/ApiDemos/res/layout/tasklist_main.xml b/samples/ApiDemos/res/layout/tasklist_main.xml new file mode 100644 index 000000000..61a17e3ef --- /dev/null +++ b/samples/ApiDemos/res/layout/tasklist_main.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/samples/ApiDemos/res/layout/tasklist_row.xml b/samples/ApiDemos/res/layout/tasklist_row.xml new file mode 100644 index 000000000..51bb31eea --- /dev/null +++ b/samples/ApiDemos/res/layout/tasklist_row.xml @@ -0,0 +1,34 @@ + + + + + + + + diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml index 5a7183c6d..1dfc1bb48 100644 --- a/samples/ApiDemos/res/values/strings.xml +++ b/samples/ApiDemos/res/values/strings.xml @@ -1286,4 +1286,18 @@ Dismiss Share - + + + + + + + Accessibility/Accessibility Node Querying + Task App Accessibility Service + TaskBack + + Task + Task %1$s %2$s + is complete + is not complete + diff --git a/samples/ApiDemos/res/xml/taskbackconfig.xml b/samples/ApiDemos/res/xml/taskbackconfig.xml new file mode 100644 index 000000000..02ff11c70 --- /dev/null +++ b/samples/ApiDemos/res/xml/taskbackconfig.xml @@ -0,0 +1,25 @@ + + + + diff --git a/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskBackService.java b/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskBackService.java new file mode 100644 index 000000000..dbbfe3a1b --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskBackService.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 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. + */ + +package com.example.android.apis.accessibility; + +import com.example.android.apis.R; + +import android.accessibilityservice.AccessibilityService; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityRecord; +import android.speech.tts.TextToSpeech; +import android.speech.tts.TextToSpeech.OnInitListener; + +import java.util.Locale; + +/** The TaskBackService listens for AccessibilityEvents, and turns them into information it can + * communicate to the user with speech. + */ +public class TaskBackService extends AccessibilityService implements OnInitListener { + + private final String LOG_TAG = "TaskBackService/onAccessibilityEvent"; + private boolean mTextToSpeechInitialized = false; + private TextToSpeech mTts = null; + private static final String SEPARATOR = ", "; + + + + /** Initializes the Text-To-Speech engine as soon as the service is connected. */ + @Override + public void onServiceConnected() { + mTts = new TextToSpeech(getApplicationContext(), this); + } + + /** Processes an AccessibilityEvent, by traversing the View's tree and putting together a + * message to speak to the user. + */ + @Override + public void onAccessibilityEvent(AccessibilityEvent event) { + if (!mTextToSpeechInitialized) { + Log.e(LOG_TAG, "Text-To-Speech engine not ready. Bailing out."); + return; + } + + int eventType = event.getEventType(); + if (eventType != AccessibilityEvent.TYPE_VIEW_CLICKED) { + return; + } + + /* This AccessibilityNodeInfo represents the view that fired the + * AccessibilityEvent. The following code will use it to traverse + * the view hierarchy, using this node as a starting point. + */ + AccessibilityNodeInfo entryNode = event.getSource(); + + /* Every method that returns an AccessibilityNodeInfo may return null, + * because the explored window is in another process and the corresponding + * View might be gone by the time your request reaches the view hierarchy." + */ + if (entryNode == null) { + return; + } + // Grab the parent of the view that fired the event. + AccessibilityNodeInfo rowNode = entryNode.getParent(); + + if (rowNode == null) { + return; + } + + /* Using this parent, get references to both child nodes, + * the label and the checkbox. + */ + AccessibilityNodeInfo labelNode = rowNode.getChild(0); + AccessibilityNodeInfo completeNode = rowNode.getChild(1); + + if (labelNode == null || completeNode == null) { + return; + } + + /* Using these to determine what the task is and whether or not + * it's complete, based on the text inside the label, and the state + * of the checkbox. + */ + + // Quick check to make sure we're not in the ApiDemos nav. + if (rowNode.getChildCount() < 2 || !rowNode.getChild(1).isCheckable()) { + return; + } + + CharSequence taskLabel = labelNode.getText(); + boolean isComplete = completeNode.isChecked(); + + String completeStr = null;; + if (isComplete) { + completeStr = getString(R.string.task_complete); + } else { + completeStr = getString(R.string.task_not_complete); + } + + String taskStr = getString(R.string.task_complete_template, taskLabel, completeStr); + StringBuilder forSpeech = new StringBuilder(taskStr); + + /* The custom listview added extra context to the event by adding + * an AccessibilityRecord to it. Extract that from the event and read it. + */ + int records = event.getRecordCount(); + + for (int i = 0; i < records; i++) { + AccessibilityRecord record = event.getRecord(i); + CharSequence contentDescription = record.getContentDescription(); + if (contentDescription != null) { + forSpeech.append(SEPARATOR).append(contentDescription); + } + } + + /* Speak the forSpeech string to the user. QUEUE_ADD adds the string to the end of the + * queue, QUEUE_FLUSH would interrupt whatever was currently being said. + */ + mTts.speak(forSpeech.toString() , TextToSpeech.QUEUE_ADD, null); + Log.d(LOG_TAG, forSpeech.toString()); + } + + @Override + public void onInterrupt() { + /* do nothing */ + } + + /** Sets a flag so that the TaskBackService knows that the Text-To-Speech engine has been + * initialized, and can now handle speaking requests. + */ + @Override + public void onInit (int status) { + if (status == TextToSpeech.SUCCESS) { + mTts.setLanguage(Locale.US); + mTextToSpeechInitialized = true; + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mTextToSpeechInitialized) { + mTts.shutdown(); + } + } +} diff --git a/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListActivity.java b/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListActivity.java new file mode 100644 index 000000000..bbc1403b8 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListActivity.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 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. + */ + +package com.example.android.apis.accessibility; + +import com.example.android.apis.R; + +import android.app.ListActivity; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +/** Starts up the task list that will interact with the AccessibilityService sample. */ +public class TaskListActivity extends ListActivity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.tasklist_main); + + // Hardcoded hand-waving here. + boolean[] checkboxes = {true, true, false, true, false, false, false}; + String[] labels = {"Take out Trash", "Do Laundry", + "Conquer World", "Nap", "Do Taxes", + "Abolish IRS", "Tea with Aunt Sharon" }; + + TaskAdapter myAdapter = new TaskAdapter(this, labels, checkboxes); + this.setListAdapter(myAdapter); + } +} diff --git a/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListView.java b/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListView.java new file mode 100644 index 000000000..a4b17cb19 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/accessibility/TaskListView.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 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. + */ + +package com.example.android.apis.accessibility; + +import com.example.android.apis.R; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; +import android.widget.BaseAdapter; +import android.widget.CheckBox; +import android.widget.ListView; +import android.widget.TextView; + + +/** Acts as a go-between for all AccessibilityEvents sent from items in the ListView, providing the + * option of sending more context to an AccessibilityService by adding more AccessiblityRecords to + * an event. + */ +public class TaskListView extends ListView { + + public TaskListView(Context context, AttributeSet attributeSet) { + super(context, attributeSet); + } + + /** + * This method will fire whenever a child event wants to send an AccessibilityEvent. As a + * result, it's a great place to add more AccessibilityRecords, if you want. In this case, + * the code is grabbing the position of the item in the list, and assuming that to be the + * priority for the task. + */ + @Override + public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { + // Add a record for ourselves as well. + AccessibilityEvent record = AccessibilityEvent.obtain(); + super.onInitializeAccessibilityEvent(record); + + int priority = (Integer) child.getTag(); + String priorityStr = "Priority: " + priority; + record.setContentDescription(priorityStr); + + event.appendRecord(record); + return true; + } +} + +/** Adds Accessibility information to individual child views of rows in the list. */ +final class TaskAdapter extends BaseAdapter{ + + private String[] mLabels = null; + private boolean[] mCheckboxes = null; + private Context mContext = null; + + public TaskAdapter(Context context, String[] labels, boolean[] checkboxes) { + super(); + mContext = context; + mLabels = labels; + mCheckboxes = checkboxes; + } + + @Override + public int getCount() { + return mLabels.length; + } + + /** Expands the views for individual list entries, and sets content descriptions for use by the + * TaskBackAccessibilityService. + */ + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if(convertView == null) { + LayoutInflater inflater = LayoutInflater.from(mContext); + convertView = inflater.inflate(R.layout.tasklist_row, parent, false); + } + + CheckBox checkbox = (CheckBox) convertView.findViewById(R.id.tasklist_finished); + checkbox.setChecked(mCheckboxes[position]); + + TextView label = (TextView)(convertView.findViewById(R.id.tasklist_label)); + label.setText(mLabels[position]); + + String contentDescription = new StringBuilder() + .append(mContext.getString(R.string.task_name)) + .append(' ') + .append(mLabels[position]).toString(); + label.setContentDescription(contentDescription); + + convertView.setTag(position); + + return convertView; + } + + @Override + public Object getItem(int position) { + return mLabels[position]; + } + + @Override + public long getItemId(int position) { + return position; + } +} diff --git a/samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html b/samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html new file mode 100644 index 000000000..eacefa10a --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/accessibility/_index.html @@ -0,0 +1,9 @@ +
    +
    Window Querying Accessibility Service
    +
    Demonstrates several new accessibility features in Ice Cream Sandwich, + including the ability for an AccessibilityService to traverse the view + hierarchy using AccessibilityNodeInfo objects, service configuration via + xml files, and adding additional information to AccessibilityEvents using + AccessibilityRecords. +
    +
    From ded0dc055f64492894445b76fdce060ae9b98b90 Mon Sep 17 00:00:00 2001 From: Xavier Ducrohet Date: Fri, 28 Oct 2011 11:27:07 -0700 Subject: [PATCH 3/4] Updated source.prop file for updated ICS SDK. Change-Id: I935e8eb29ae52c56e4f897c69c808010b701e195 --- samples/source.properties | 2 +- sdk/images_armeabi-v7a_source.properties | 2 +- sdk/plat_tools_source.properties | 2 +- sdk/platform_source.properties | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/source.properties b/samples/source.properties index 7cb1d33df..c21a0412f 100644 --- a/samples/source.properties +++ b/samples/source.properties @@ -1,4 +1,4 @@ Pkg.UserSrc=false -Pkg.Revision=1 +Pkg.Revision=2 AndroidVersion.ApiLevel=14 #AndroidVersion.CodeName= diff --git a/sdk/images_armeabi-v7a_source.properties b/sdk/images_armeabi-v7a_source.properties index aa7d1aab4..9499576f1 100644 --- a/sdk/images_armeabi-v7a_source.properties +++ b/sdk/images_armeabi-v7a_source.properties @@ -1,6 +1,6 @@ Pkg.Desc=Android SDK Platform 4.0 Pkg.UserSrc=false -Pkg.Revision=1 +Pkg.Revision=2 AndroidVersion.ApiLevel=14 #AndroidVersion.CodeName= SystemImage.Abi=armeabi-v7a diff --git a/sdk/plat_tools_source.properties b/sdk/plat_tools_source.properties index bb8fd8c58..3da944815 100644 --- a/sdk/plat_tools_source.properties +++ b/sdk/plat_tools_source.properties @@ -1,2 +1,2 @@ Pkg.UserSrc=false -Pkg.Revision=9 \ No newline at end of file +Pkg.Revision=10 \ No newline at end of file diff --git a/sdk/platform_source.properties b/sdk/platform_source.properties index 5e3ef1330..5a6c4df4d 100644 --- a/sdk/platform_source.properties +++ b/sdk/platform_source.properties @@ -1,7 +1,7 @@ Pkg.Desc=Android SDK Platform 4.0 Pkg.UserSrc=false Platform.Version=4.0 -Pkg.Revision=1 +Pkg.Revision=2 AndroidVersion.ApiLevel=14 #AndroidVersion.CodeName= Layoutlib.Api=7 From e864636c554efa18f83ad9fa405058b51d531998 Mon Sep 17 00:00:00 2001 From: Jack Palevich Date: Thu, 27 Oct 2011 13:05:24 -0700 Subject: [PATCH 4/4] Remove Graphics > OpenGL ES > Hidden Activity from Api Demos This activity was accidentally added to the Api Demos manifest in an earlier checkin. Because the corresponding Java classes were never checked in, the activity never actually worked. Change-Id: I7a7c8c90e8e6b9689f87720fc7f4d53556c2f227 --- samples/ApiDemos/AndroidManifest.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index 064d05887..97d3ac4fb 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -2247,16 +2247,6 @@
    - - - - - - -