am 894a63dd: emulator: opengl: Add custom_write optimization to encoder.
* commit '894a63dd6eb8a1c675c21a8a10eff8c0118890c8':
emulator: opengl: Add custom_write optimization to encoder.
diff --git a/apps/CustomLocale/AndroidManifest.xml b/apps/CustomLocale/AndroidManifest.xml
index 9dfa896..0a446de 100644
--- a/apps/CustomLocale/AndroidManifest.xml
+++ b/apps/CustomLocale/AndroidManifest.xml
@@ -13,25 +13,40 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
- android:versionName="1.0" package="com.android.customlocale">
+ android:versionName="1.0"
+ package="com.android.customlocale2"
+ >
+
+ <uses-sdk android:minSdkVersion="3" />
+
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+
<application
android:icon="@drawable/icon"
- android:label="@string/app_name">
+ android:label="@string/app_name" >
+
<activity
- android:label="@string/app_name" android:name="CustomLocaleActivity">
+ android:label="@string/app_name"
+ android:name="CustomLocaleActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
<activity
- android:name="NewLocaleDialog"
- android:theme="@android:style/Theme.Dialog" />
+ android:theme="@android:style/Theme.Dialog"
+ android:name="NewLocaleDialog" />
+
+ <receiver android:name="CustomLocaleReceiver" >
+ <intent-filter>
+ <action android:name="com.android.intent.action.SET_LOCALE" />
+ </intent-filter>
+ </receiver>
</application>
- <uses-sdk android:minSdkVersion="3" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
</manifest>
diff --git a/apps/CustomLocale/res/layout/list_item.xml b/apps/CustomLocale/res/layout/list_item.xml
deleted file mode 100644
index 0ffb8b0..0000000
--- a/apps/CustomLocale/res/layout/list_item.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="5dip">
- <TextView
- android:id="@+id/locale_code"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="?android:textAppearanceLarge"
- android:layout_weight="1"
- android:text="@string/locale_default" />
- <TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/locale_name"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="?android:textAppearance"
- android:layout_weight="1" />
-</LinearLayout>
\ No newline at end of file
diff --git a/apps/CustomLocale/res/layout/main.xml b/apps/CustomLocale/res/layout/main.xml
index 55bd90c..e700a8b 100644
--- a/apps/CustomLocale/res/layout/main.xml
+++ b/apps/CustomLocale/res/layout/main.xml
@@ -17,7 +17,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -25,13 +26,15 @@
android:text="@string/header_current_locale"
android:textAppearance="@style/TextAppearance.header"
android:gravity="center_horizontal"
- android:background="@color/header_background" />
+ android:background="@color/header_background"
+ />
<TextView
android:id="@+id/current_locale"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
- android:padding="5dip" />
+ android:padding="5dip"
+ />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -39,24 +42,61 @@
android:text="@string/header_locale_list"
android:textAppearance="@style/TextAppearance.header"
android:gravity="center_horizontal"
- android:background="@color/header_background" />
- <ListView
- android:id="@id/android:list"
+ android:background="@color/header_background"
+ />
+
+ <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
- android:padding="8dip" />
- <TextView
- android:id="@id/android:empty"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="@string/no_data_label" />
- <Button
- android:id="@+id/new_locale"
+ >
+ <ListView
+ android:id="@id/android:list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fastScrollEnabled="true"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:padding="8dip"
+ />
+ <TextView
+ android:id="@id/android:empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/no_data_label"
+ android:gravity="center"
+ />
+ </FrameLayout>
+
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:text="@string/add_new_locale_button" />
+ >
+ <Button
+ android:id="@+id/select_locale_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.9"
+ android:layout_gravity="center_vertical"
+ android:text="@string/select_locale_button"
+ />
+ <Button
+ android:id="@+id/add_new_locale_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="center_vertical"
+ android:text="@string/add_new_locale_button"
+ />
+ <Button
+ android:id="@+id/remove_locale_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginLeft="5dip"
+ android:layout_gravity="center_vertical"
+ android:text="@string/remove_locale_button"
+ />
+ </LinearLayout>
</LinearLayout>
diff --git a/apps/CustomLocale/res/values-fr/strings.xml b/apps/CustomLocale/res/values-fr/strings.xml
index 8852a9a..8c9bc38 100644
--- a/apps/CustomLocale/res/values-fr/strings.xml
+++ b/apps/CustomLocale/res/values-fr/strings.xml
@@ -15,11 +15,34 @@
-->
<resources>
<string name="app_name">Locales Personalisées</string>
- <string name="add_new_locale_button">Ajouter une nouvelle locale</string>
- <string name="new_locale_label">Code de la nouvelle locale:</string>
- <string name="add_button">Ajouter</string>
- <string name="no_data_label">Aucune locale</string>
+
+ <!-- Top labels in CustomLocaleActivity -->
+
<string name="header_current_locale">Locale courrante</string>
<string name="header_locale_list">Liste des locales</string>
- <string name="add_select_button">Ajouter et sélectionner</string>
+ <string name="no_data_label">Aucune locale</string>
+
+ <!-- Buttons in CustomLocaleActivity -->
+
+ <string name="select_locale_button">Choisir</string>
+ <string name="select_locale_1s_button">Choisir \'%1$s\'</string>
+ <string name="add_new_locale_button">Ajouter\u2026</string>
+ <string name="remove_locale_button">Retirer\u2026</string>
+
+ <!-- Toast status in CustomLocaleActivity -->
+
+ <string name="removed_custom_locale_1s">Locale supprimée: %1$s</string>
+ <string name="select_locale_1s">Locale choisie: %1$s</string>
+ <string name="added_custom_locale_1s">Locale ajoutée: %1$s</string>
+
+ <!-- NewLocaleDialog -->
+
+ <string name="new_locale_label">Code de la nouvelle locale:</string>
+ <string name="add_button">Ajouter</string>
+ <string name="add_select_button">Ajouter et choisir</string>
+
+ <string name="confirm_remove_locale_1s">Voulez-vous supprimer la locale personalisée \'%1$s\' ?</string>
+ <string name="confirm_remove_locale_yes">Oui</string>
+ <string name="confirm_remove_locale_no">Non</string>
+
</resources>
diff --git a/apps/CustomLocale/res/values/strings.xml b/apps/CustomLocale/res/values/strings.xml
index 313fb87..955521c 100644
--- a/apps/CustomLocale/res/values/strings.xml
+++ b/apps/CustomLocale/res/values/strings.xml
@@ -15,12 +15,37 @@
-->
<resources>
<string name="app_name">Custom Locale</string>
- <string name="locale_default">ex_EX</string>
- <string name="add_new_locale_button">Add New Locale</string>
- <string name="new_locale_label">New locale code:</string>
- <string name="add_button">Add</string>
- <string name="no_data_label">No data</string>
+
+ <!-- Top labels in CustomLocaleActivity -->
+
<string name="header_current_locale">Current Locale</string>
<string name="header_locale_list">Locale List</string>
+ <string name="no_data_label">No data</string>
+
+ <!-- Buttons in CustomLocaleActivity -->
+
+ <string name="select_locale_button">Select</string>
+ <string name="select_locale_1s_button">Select \'%1$s\'</string>
+ <string name="add_new_locale_button">Add New\u2026</string>
+ <string name="remove_locale_button">Remove\u2026</string>
+
+ <!-- Toast status in CustomLocaleActivity -->
+
+ <string name="removed_custom_locale_1s">Removed custom locale: %1$s</string>
+ <string name="select_locale_1s">Select locale: %1$s</string>
+ <string name="added_custom_locale_1s">Added custom locale: %1$s</string>
+
+ <!-- NewLocaleDialog -->
+
+ <string name="new_locale_label">New locale code:</string>
+ <string name="add_button">Add</string>
<string name="add_select_button">Add and Select</string>
+
+ <string name="confirm_remove_locale_1s">Do you want to remove the custom locale \'%1$s\'?</string>
+ <string name="confirm_remove_locale_yes">Yes</string>
+ <string name="confirm_remove_locale_no">No</string>
+
+ <!-- Locale hint in textfield. Not translated -->
+ <string name="locale_default">ex_EX</string>
+
</resources>
diff --git a/apps/CustomLocale/src/com/android/customlocale/CustomLocaleActivity.java b/apps/CustomLocale/src/com/android/customlocale/CustomLocaleActivity.java
deleted file mode 100644
index 69b9c5b..0000000
--- a/apps/CustomLocale/src/com/android/customlocale/CustomLocaleActivity.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (C) 2009 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.android.customlocale;
-
-
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.ListActivity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.Button;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.SimpleAdapter;
-import android.widget.TextView;
-import android.widget.Toast;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Displays the list of system locales as well as maintain a custom list of user
- * locales. The user can select a locale and apply it or it can create or remove
- * a custom locale.
- */
-public class CustomLocaleActivity extends ListActivity {
-
- private static final String CUSTOM_LOCALES_SEP = " ";
- private static final String CUSTOM_LOCALES = "custom_locales";
- private static final String KEY_CUSTOM = "custom";
- private static final String KEY_NAME = "name";
- private static final String KEY_CODE = "code";
-
- private static final String TAG = "LocaleSetup";
- private static final boolean DEBUG = true;
-
- /** Request code returned when the NewLocaleDialog activity finishes. */
- private static final int UPDATE_LIST = 42;
- /** Menu item id for applying a locale */
- private static final int MENU_APPLY = 43;
- /** Menu item id for removing a custom locale */
- private static final int MENU_REMOVE = 44;
-
- /** List view displaying system and custom locales. */
- private ListView mListView;
- /** Textview used to display current locale */
- private TextView mCurrentLocaleTextView;
- /** Private shared preferences of this activity. */
- private SharedPreferences mPrefs;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- mPrefs = getPreferences(MODE_PRIVATE);
-
- Button newLocaleButton = (Button) findViewById(R.id.new_locale);
-
- newLocaleButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- Intent i = new Intent(CustomLocaleActivity.this, NewLocaleDialog.class);
- startActivityForResult(i, UPDATE_LIST);
- }
- });
-
- mListView = (ListView) findViewById(android.R.id.list);
- mListView.setFocusable(true);
- mListView.setFocusableInTouchMode(true);
- mListView.requestFocus();
- registerForContextMenu(mListView);
- setupLocaleList();
-
- mCurrentLocaleTextView = (TextView) findViewById(R.id.current_locale);
- displayCurrentLocale();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode == UPDATE_LIST && resultCode == RESULT_OK && data != null) {
- String locale = data.getExtras().getString(NewLocaleDialog.INTENT_EXTRA_LOCALE);
- if (locale != null && locale.length() > 0) {
- // Get current custom locale list
- String customLocales = mPrefs.getString(CUSTOM_LOCALES, null);
-
- // Update
- if (customLocales == null) {
- customLocales = locale;
- } else {
- customLocales += CUSTOM_LOCALES_SEP + locale;
- }
-
- // Save prefs
- if (DEBUG) {
- Log.d(TAG, "add/customLocales: " + customLocales);
- }
- mPrefs.edit().putString(CUSTOM_LOCALES, customLocales).commit();
-
- Toast.makeText(this, "Added custom locale: " + locale, Toast.LENGTH_SHORT).show();
-
- // Update list view
- setupLocaleList();
-
- // Find the item to select it in the list view
- ListAdapter a = mListView.getAdapter();
- for (int i = 0; i < a.getCount(); i++) {
- Object o = a.getItem(i);
- if (o instanceof Map<?, ?>) {
- String code = ((Map<String, String>) o).get(KEY_CODE);
- if (code != null && code.equals(locale)) {
- mListView.setSelection(i);
- break;
- }
- }
- }
-
- if (data.getExtras().getBoolean(NewLocaleDialog.INTENT_EXTRA_SELECT)) {
- selectLocale(locale);
- }
- }
- }
- }
-
- private void setupLocaleList() {
- if (DEBUG) {
- Log.d(TAG, "Update locate list");
- }
-
- ArrayList<Map<String, String>> data = new ArrayList<Map<String, String>>();
-
- // Insert all system locales
- String[] locales = getAssets().getLocales();
- for (String locale : locales) {
- Locale loc = new Locale(locale);
-
- Map<String, String> map = new HashMap<String, String>(1);
- map.put(KEY_CODE, locale);
- map.put(KEY_NAME, loc.getDisplayName());
- data.add(map);
- }
- locales = null;
-
- // Insert all custom locales
- String customLocales = mPrefs.getString(CUSTOM_LOCALES, "");
- if (DEBUG) {
- Log.d(TAG, "customLocales: " + customLocales);
- }
- for (String locale : customLocales.split(CUSTOM_LOCALES_SEP)) {
- if (locale != null && locale.length() > 0) {
- Locale loc = new Locale(locale);
-
- Map<String, String> map = new HashMap<String, String>(1);
- map.put(KEY_CODE, locale);
- map.put(KEY_NAME, loc.getDisplayName() + " [Custom]");
- // the presence of the "custom" key marks it as custom.
- map.put(KEY_CUSTOM, "");
- data.add(map);
- }
- }
-
- // Sort all locales by code
- Collections.sort(data, new Comparator<Map<String, String>>() {
- public int compare(Map<String, String> lhs, Map<String, String> rhs) {
- return lhs.get(KEY_CODE).compareTo(rhs.get(KEY_CODE));
- }
- });
-
- // Update the list view adapter
- mListView.setAdapter(new SimpleAdapter(this, data, R.layout.list_item, new String[] {
- KEY_CODE, KEY_NAME}, new int[] {R.id.locale_code, R.id.locale_name}));
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
-
- if (menuInfo instanceof AdapterContextMenuInfo) {
- int position = ((AdapterContextMenuInfo) menuInfo).position;
- Object o = mListView.getItemAtPosition(position);
- if (o instanceof Map<?, ?>) {
- String locale = ((Map<String, String>) o).get(KEY_CODE);
- String custom = ((Map<String, String>) o).get(KEY_CUSTOM);
-
- if (custom == null) {
- menu.setHeaderTitle("System Locale");
- menu.add(0, MENU_APPLY, 0, "Apply");
- } else {
- menu.setHeaderTitle("Custom Locale");
- menu.add(0, MENU_APPLY, 0, "Apply");
- menu.add(0, MENU_REMOVE, 0, "Remove");
- }
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public boolean onContextItemSelected(MenuItem item) {
-
- String pendingLocale = null;
- boolean is_custom = false;
-
- ContextMenuInfo menuInfo = item.getMenuInfo();
- if (menuInfo instanceof AdapterContextMenuInfo) {
- int position = ((AdapterContextMenuInfo) menuInfo).position;
- Object o = mListView.getItemAtPosition(position);
- if (o instanceof Map<?, ?>) {
- pendingLocale = ((Map<String, String>) o).get(KEY_CODE);
- is_custom = ((Map<String, String>) o).get(KEY_CUSTOM) != null;
- }
- }
-
- if (pendingLocale == null) {
- // should never happen
- return super.onContextItemSelected(item);
- }
-
- if (item.getItemId() == MENU_REMOVE) {
- // Get current custom locale list
- String customLocales = mPrefs.getString(CUSTOM_LOCALES, "");
-
- if (DEBUG) {
- Log.d(TAG, "Remove " + pendingLocale + " from custom locales: " + customLocales);
- }
-
- // Update
- StringBuilder sb = new StringBuilder();
- for (String locale : customLocales.split(CUSTOM_LOCALES_SEP)) {
- if (locale != null && locale.length() > 0 && !locale.equals(pendingLocale)) {
- if (sb.length() > 0) {
- sb.append(CUSTOM_LOCALES_SEP);
- }
- sb.append(locale);
- }
- }
- String newLocales = sb.toString();
- if (!newLocales.equals(customLocales)) {
- // Save prefs
- mPrefs.edit().putString(CUSTOM_LOCALES, customLocales).commit();
-
- Toast.makeText(this, "Removed custom locale: " + pendingLocale, Toast.LENGTH_SHORT)
- .show();
- }
-
- } else if (item.getItemId() == MENU_APPLY) {
- selectLocale(pendingLocale);
- }
-
- return super.onContextItemSelected(item);
- }
-
- private void selectLocale(String locale) {
- if (DEBUG) {
- Log.d(TAG, "Select locale " + locale);
- }
-
- try {
- IActivityManager am = ActivityManagerNative.getDefault();
- Configuration config = am.getConfiguration();
-
- Locale loc = null;
-
- String[] langCountry = locale.split("_");
- if (langCountry.length == 2) {
- loc = new Locale(langCountry[0], langCountry[1]);
- } else {
- loc = new Locale(locale);
- }
-
- config.locale = loc;
-
- // indicate this isn't some passing default - the user wants this
- // remembered
- config.userSetLocale = true;
-
- am.updateConfiguration(config);
-
- Toast.makeText(this, "Select locale: " + locale, Toast.LENGTH_SHORT).show();
- } catch (RemoteException e) {
- if (DEBUG) {
- Log.e(TAG, "Select locale failed", e);
- }
- }
- }
-
- private void displayCurrentLocale() {
- try {
- IActivityManager am = ActivityManagerNative.getDefault();
- Configuration config = am.getConfiguration();
-
- if (config.locale != null) {
- String text = String.format("%s - %s",
- config.locale.toString(),
- config.locale.getDisplayName());
- mCurrentLocaleTextView.setText(text);
- }
- } catch (RemoteException e) {
- if (DEBUG) {
- Log.e(TAG, "get current locale failed", e);
- }
- }
- }
-}
diff --git a/apps/CustomLocale/src/com/android/customlocale2/ChangeLocale.java b/apps/CustomLocale/src/com/android/customlocale2/ChangeLocale.java
new file mode 100755
index 0000000..8757064
--- /dev/null
+++ b/apps/CustomLocale/src/com/android/customlocale2/ChangeLocale.java
@@ -0,0 +1,78 @@
+/*
+ * 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.android.customlocale2;
+
+
+import java.util.Locale;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.content.res.Configuration;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Helper class to change the system locale.
+ */
+public final class ChangeLocale {
+
+ private static final String TAG = ChangeLocale.class.getSimpleName();
+ private static final boolean DEBUG = true;
+
+ /**
+ * Sets the system locale to the new one specified.
+ *
+ * @param locale A locale name in the form "ab_AB". Must not be null or empty.
+ * @return True if the locale was succesfully changed.
+ */
+ public static boolean changeSystemLocale(String locale) {
+ if (DEBUG) {
+ Log.d(TAG, "Change locale to: " + locale);
+ }
+
+ try {
+ IActivityManager am = ActivityManagerNative.getDefault();
+ Configuration config = am.getConfiguration();
+
+ Locale loc = null;
+
+ String[] langCountry = locale.split("_");
+ if (langCountry.length == 2) {
+ loc = new Locale(langCountry[0], langCountry[1]);
+ } else {
+ loc = new Locale(locale);
+ }
+
+ config.locale = loc;
+
+ // indicate this isn't some passing default - the user wants this
+ // remembered
+ config.userSetLocale = true;
+
+ am.updateConfiguration(config);
+
+ return true;
+
+ } catch (RemoteException e) {
+ if (DEBUG) {
+ Log.e(TAG, "Change locale failed", e);
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/apps/CustomLocale/src/com/android/customlocale2/CustomLocaleActivity.java b/apps/CustomLocale/src/com/android/customlocale2/CustomLocaleActivity.java
new file mode 100644
index 0000000..3bf7993
--- /dev/null
+++ b/apps/CustomLocale/src/com/android/customlocale2/CustomLocaleActivity.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2009 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.android.customlocale2;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Locale;
+
+import android.app.ActivityManagerNative;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.IActivityManager;
+import android.app.ListActivity;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+
+/**
+ * Displays the list of system locales as well as maintain a custom list of user
+ * locales. The user can select a locale and apply it or it can create or remove
+ * a custom locale.
+ */
+public class CustomLocaleActivity extends ListActivity {
+
+ private static final String TAG = "CustomLocale";
+ private static final boolean DEBUG = true;
+
+ private static final int DLG_REMOVE_ID = 0;
+
+ private static final String CUSTOM_LOCALES_SEP = " ";
+ private static final String CUSTOM_LOCALES = "custom_locales";
+
+ /** Request code returned when the NewLocaleDialog activity finishes. */
+ private static final int UPDATE_LIST = 42;
+ /** Menu item id for applying a locale */
+ private static final int MENU_APPLY = 43;
+ /** Menu item id for removing a custom locale */
+ private static final int MENU_REMOVE = 44;
+
+ /** List view displaying system and custom locales. */
+ private ListView mListView;
+ /** Textview used to display current locale */
+ private TextView mCurrentLocaleTextView;
+ /** Private shared preferences of this activity. */
+ private SharedPreferences mPrefs;
+
+ private Button mRemoveLocaleButton;
+ private Button mSelectLocaleButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ mPrefs = getPreferences(MODE_PRIVATE);
+
+ Button addLocaleButton = (Button) findViewById(R.id.add_new_locale_button);
+ mRemoveLocaleButton = (Button) findViewById(R.id.remove_locale_button);
+ mSelectLocaleButton = (Button) findViewById(R.id.select_locale_button);
+
+ addLocaleButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ onAddNewLocale();
+ }
+ });
+
+ mRemoveLocaleButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showDialog(DLG_REMOVE_ID);
+ }
+ });
+
+ mSelectLocaleButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onSelectLocale();
+ }
+ });
+
+ mListView = (ListView) findViewById(android.R.id.list);
+ mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ mListView.setItemsCanFocus(false);
+ mListView.setFocusable(true);
+ mListView.setFocusableInTouchMode(true);
+ mListView.requestFocus();
+ setupLocaleList();
+
+ mCurrentLocaleTextView = (TextView) findViewById(R.id.current_locale);
+ displayCurrentLocale();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ updateLocaleButtons();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if (requestCode == UPDATE_LIST && resultCode == RESULT_OK && data != null) {
+ String locale = data.getExtras().getString(NewLocaleDialog.INTENT_EXTRA_LOCALE);
+ if (locale != null && locale.length() > 0) {
+ // Get current custom locale list
+ String customLocales = mPrefs.getString(CUSTOM_LOCALES, null);
+
+ // Update
+ if (customLocales == null) {
+ customLocales = locale;
+ } else {
+ customLocales += CUSTOM_LOCALES_SEP + locale;
+ }
+
+ // Save prefs
+ if (DEBUG) {
+ Log.d(TAG, "add/customLocales: " + customLocales);
+ }
+ mPrefs.edit().putString(CUSTOM_LOCALES, customLocales).commit();
+
+ Toast.makeText(this,
+ getString(R.string.added_custom_locale_1s, locale),
+ Toast.LENGTH_SHORT)
+ .show();
+
+ // Update list view
+ setupLocaleList();
+
+ // Find the item to select it in the list view
+ checkLocaleInList(locale);
+
+ if (data.getExtras().getBoolean(NewLocaleDialog.INTENT_EXTRA_SELECT)) {
+ changeSystemLocale(locale);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ super.onListItemClick(l, v, position, id);
+ updateLocaleButtons();
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+
+ if (menuInfo instanceof AdapterContextMenuInfo) {
+ int position = ((AdapterContextMenuInfo) menuInfo).position;
+ Object o = mListView.getItemAtPosition(position);
+ if (o instanceof LocaleInfo) {
+ if (((LocaleInfo) o).isCustom()) {
+ menu.setHeaderTitle("System Locale");
+ menu.add(0, MENU_APPLY, 0, "Apply");
+ } else {
+ menu.setHeaderTitle("Custom Locale");
+ menu.add(0, MENU_APPLY, 0, "Apply");
+ menu.add(0, MENU_REMOVE, 0, "Remove");
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ if (id == DLG_REMOVE_ID) {
+ return createRemoveLocaleDialog();
+ }
+ return super.onCreateDialog(id);
+ }
+
+ //--- private parts ---
+
+ private void setupLocaleList() {
+ if (DEBUG) {
+ Log.d(TAG, "Update locate list");
+ }
+
+ ArrayList<LocaleInfo> data = new ArrayList<LocaleInfo>();
+
+ // Insert all system locales
+ String[] locales = getAssets().getLocales();
+ for (String locale : locales) {
+ if (locale != null && locale.length() > 0) {
+ Locale loc = new Locale(locale);
+ data.add(new LocaleInfo(locale, loc.getDisplayName()));
+ }
+ }
+ locales = null;
+
+ // Insert all custom locales
+ String customLocales = mPrefs.getString(CUSTOM_LOCALES, "");
+ if (DEBUG) {
+ Log.d(TAG, "customLocales: " + customLocales);
+ }
+ for (String locale : customLocales.split(CUSTOM_LOCALES_SEP)) {
+ if (locale != null && locale.length() > 0) {
+ Locale loc = new Locale(locale);
+ data.add(new LocaleInfo(
+ locale,
+ loc.getDisplayName(),
+ true /*custom*/));
+ }
+ }
+
+ // Sort all locales by code
+ Collections.sort(data, new Comparator<LocaleInfo>() {
+ public int compare(LocaleInfo lhs, LocaleInfo rhs) {
+ return lhs.getLocale().compareTo(rhs.getLocale());
+ }
+ });
+
+ // Update the list view adapter
+ mListView.setAdapter(new ArrayAdapter<LocaleInfo>(
+ this,
+ android.R.layout.simple_list_item_single_choice,
+ data));
+ updateLocaleButtons();
+ }
+
+ private void changeSystemLocale(String locale) {
+ if (ChangeLocale.changeSystemLocale(locale)) {
+ Toast.makeText(this,
+ getString(R.string.select_locale_1s, locale),
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ }
+
+ private void displayCurrentLocale() {
+ try {
+ IActivityManager am = ActivityManagerNative.getDefault();
+ Configuration config = am.getConfiguration();
+
+ if (config.locale != null) {
+ String text = String.format("%1$s - %2$s",
+ config.locale.toString(),
+ config.locale.getDisplayName());
+ mCurrentLocaleTextView.setText(text);
+
+ checkLocaleInList(config.locale.toString());
+ }
+ } catch (RemoteException e) {
+ if (DEBUG) {
+ Log.e(TAG, "get current locale failed", e);
+ }
+ }
+ }
+
+ /** Find the locale by code to select it in the list view */
+ private void checkLocaleInList(String locale) {
+ ListAdapter a = mListView.getAdapter();
+ for (int i = 0; i < a.getCount(); i++) {
+ Object o = a.getItem(i);
+ if (o instanceof LocaleInfo) {
+ String code = ((LocaleInfo) o).getLocale();
+ if (code != null && code.equals(locale)) {
+ mListView.setSelection(i);
+ mListView.clearChoices();
+ mListView.setItemChecked(i, true);
+ updateLocaleButtons();
+ break;
+ }
+ }
+ }
+ }
+
+ private LocaleInfo getCheckedLocale() {
+ int pos = mListView.getCheckedItemPosition();
+ ListAdapter a = mListView.getAdapter();
+ int n = a.getCount();
+ if (pos >= 0 && pos < n) {
+ Object o = a.getItem(pos);
+ if (o instanceof LocaleInfo) {
+ return (LocaleInfo) o;
+ }
+ }
+
+ return null;
+ }
+
+ /** Update the Select/Remove buttons based on the currently checked locale. */
+ private void updateLocaleButtons() {
+ LocaleInfo info = getCheckedLocale();
+ if (info != null) {
+ // Enable it
+ mSelectLocaleButton.setEnabled(true);
+ mSelectLocaleButton.setText(
+ getString(R.string.select_locale_1s_button, info.getLocale()));
+
+ // Enable the remove button only for custom locales and set the tag to the locale
+ mRemoveLocaleButton.setEnabled(info.isCustom());
+ } else {
+ // If nothing is selected, disable the buttons
+ mSelectLocaleButton.setEnabled(false);
+ mSelectLocaleButton.setText(R.string.select_locale_button);
+
+ mRemoveLocaleButton.setEnabled(false);
+ }
+ }
+
+ /** Invoked by the button "Add new..." */
+ private void onAddNewLocale() {
+ Intent i = new Intent(CustomLocaleActivity.this, NewLocaleDialog.class);
+ startActivityForResult(i, UPDATE_LIST);
+ }
+
+ /** Invoked by the button Select / mSelectLocaleButton */
+ private void onSelectLocale() {
+ LocaleInfo info = getCheckedLocale();
+ if (info != null) {
+ changeSystemLocale(info.getLocale());
+ }
+ }
+
+ /**
+ * Invoked by the button Remove / mRemoveLocaleButton.
+ * Creates a dialog to ask for confirmation before actually remove the custom locale.
+ */
+ private Dialog createRemoveLocaleDialog() {
+
+ LocaleInfo info = getCheckedLocale();
+ final String localeToRemove = info == null ? "<error>" : info.getLocale();
+
+ AlertDialog.Builder b = new AlertDialog.Builder(this);
+ b.setMessage(getString(R.string.confirm_remove_locale_1s, localeToRemove));
+ b.setCancelable(false);
+ b.setPositiveButton(R.string.confirm_remove_locale_yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ removeCustomLocale(localeToRemove);
+ dismissDialog(DLG_REMOVE_ID);
+ }
+ });
+ b.setNegativeButton(R.string.confirm_remove_locale_no,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismissDialog(DLG_REMOVE_ID);
+ }
+ });
+
+ return b.create();
+ }
+
+ private void removeCustomLocale(String localeToRemove) {
+ // Get current custom locale list
+ String oldLocales = mPrefs.getString(CUSTOM_LOCALES, "");
+
+ if (DEBUG) {
+ Log.d(TAG, "Remove " + localeToRemove + " from custom locales: " + oldLocales);
+ }
+
+ // Update
+ StringBuilder sb = new StringBuilder();
+ for (String locale : oldLocales.split(CUSTOM_LOCALES_SEP)) {
+ if (locale != null && locale.length() > 0 && !locale.equals(localeToRemove)) {
+ if (sb.length() > 0) {
+ sb.append(CUSTOM_LOCALES_SEP);
+ }
+ sb.append(locale);
+ }
+ }
+
+ String newLocales = sb.toString();
+ if (!newLocales.equals(oldLocales)) {
+ // Save prefs
+ boolean ok = mPrefs.edit().putString(CUSTOM_LOCALES, newLocales).commit();
+ if (DEBUG) {
+ Log.d(TAG, "Prefs commit:" + Boolean.toString(ok) + ". Saved: " + newLocales);
+ }
+
+ Toast.makeText(this,
+ getString(R.string.removed_custom_locale_1s, localeToRemove),
+ Toast.LENGTH_SHORT)
+ .show();
+
+ // Update list view
+ setupLocaleList();
+ }
+ }
+
+ /**
+ * Immutable structure that holds the information displayed by a list view item.
+ */
+ private static class LocaleInfo {
+ private final String mLocale;
+ private final String mDisplayName;
+ private final boolean mIsCustom;
+
+ public LocaleInfo(String locale, String displayName, boolean isCustom) {
+ mLocale = locale;
+ mDisplayName = displayName;
+ mIsCustom = isCustom;
+ }
+
+ public LocaleInfo(String locale, String displayName) {
+ this(locale, displayName, false /*custom*/);
+ }
+
+ public String getLocale() {
+ return mLocale;
+ }
+
+ public boolean isCustom() {
+ return mIsCustom;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(mLocale)
+ .append(" - ")
+ .append(mDisplayName);
+ if (mIsCustom) {
+ sb.append(" [Custom]");
+ }
+ return sb.toString();
+ }
+ }
+}
diff --git a/apps/CustomLocale/src/com/android/customlocale2/CustomLocaleReceiver.java b/apps/CustomLocale/src/com/android/customlocale2/CustomLocaleReceiver.java
new file mode 100755
index 0000000..30d886e
--- /dev/null
+++ b/apps/CustomLocale/src/com/android/customlocale2/CustomLocaleReceiver.java
@@ -0,0 +1,82 @@
+/*
+ * 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.android.customlocale2;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+//-----------------------------------------------
+
+/**
+ * Broadcast receiver that can change the system's locale.
+ * <p/>
+ * This allows an external script such as an automated testing framework
+ * to easily trigger a locale change on an emulator as such:
+ * <pre>
+ * $ adb shell am broadcast -a com.android.intent.action.SET_LOCALE \
+ * --es com.android.intent.extra.LOCALE en_US
+ * </pre>
+ */
+public class CustomLocaleReceiver extends BroadcastReceiver {
+
+ private static final String TAG = CustomLocaleReceiver.class.getSimpleName();
+ private static final boolean DEBUG = true;
+
+ /** Intent action that triggers this receiver. */
+ public static final String ACTION_SET_LOCALE = "com.android.intent.action.SET_LOCALE";
+ /** An extra String that specifies the locale to set, in the form "en_US". */
+ public static final String EXTRA_LOCALE = "com.android.intent.extra.LOCALE";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ setResult(Activity.RESULT_CANCELED, null, null);
+ if (intent == null || ! ACTION_SET_LOCALE.equals(intent.getAction())) {
+ if (DEBUG) {
+ Log.d(TAG, "Invalid intent: " + (intent == null ? "null" : intent.toString()));
+ }
+ return;
+ }
+
+ String locale = intent.getStringExtra(EXTRA_LOCALE);
+
+ // Enforce the locale string is either in the form "ab" or "ab_cd"
+ boolean is_ok = locale != null;
+ is_ok = is_ok && (locale.length() == 2 || locale.length() == 5);
+ if (is_ok && locale.length() >= 2) {
+ is_ok = Character.isLetter(locale.charAt(0)) &&
+ Character.isLetter(locale.charAt(1));
+ }
+ if (is_ok && locale.length() == 5) {
+ is_ok = locale.charAt(2) == '_' &&
+ Character.isLetter(locale.charAt(3)) &&
+ Character.isLetter(locale.charAt(4));
+ }
+
+ if (!is_ok && DEBUG) {
+ Log.e(TAG, "Invalid locale: expected ab_CD but got " + locale);
+ } else if (is_ok) {
+ ChangeLocale.changeSystemLocale(locale);
+ setResult(Activity.RESULT_OK, locale, null);
+ }
+ }
+
+}
+
+
diff --git a/apps/CustomLocale/src/com/android/customlocale/NewLocaleDialog.java b/apps/CustomLocale/src/com/android/customlocale2/NewLocaleDialog.java
similarity index 93%
rename from apps/CustomLocale/src/com/android/customlocale/NewLocaleDialog.java
rename to apps/CustomLocale/src/com/android/customlocale2/NewLocaleDialog.java
index 04f7222..3764fd6 100644
--- a/apps/CustomLocale/src/com/android/customlocale/NewLocaleDialog.java
+++ b/apps/CustomLocale/src/com/android/customlocale2/NewLocaleDialog.java
@@ -14,14 +14,12 @@
* limitations under the License.
*/
-package com.android.customlocale;
+package com.android.customlocale2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
-import android.text.TextUtils;
import android.util.Log;
-import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
@@ -41,7 +39,6 @@
private Button mButtonAdd;
private Button mButtonAddSelect;
private EditText mEditText;
- private boolean mWasEmpty;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -50,7 +47,6 @@
setContentView(R.layout.new_locale);
mEditText = (EditText) findViewById(R.id.value);
- mWasEmpty = true;
mButtonAdd = (Button) findViewById(R.id.add);
mButtonAdd.setOnClickListener(this);
@@ -62,7 +58,7 @@
public void onClick(View v) {
String locale = mEditText.getText().toString();
boolean select = v == mButtonAddSelect;
-
+
if (DEBUG) {
Log.d(TAG, "New Locale: " + locale + (select ? " + select" : ""));
}
diff --git a/apps/Development/src/com/android/development/PackageSummary.java b/apps/Development/src/com/android/development/PackageSummary.java
index 58ab0f7..d621d4e 100644
--- a/apps/Development/src/com/android/development/PackageSummary.java
+++ b/apps/Development/src/com/android/development/PackageSummary.java
@@ -251,7 +251,7 @@
private final static void setItemText(Button item, PackageInfo pi,
String className)
{
- item.setText(className.substring(pi.packageName.length()+1));
+ item.setText(className.substring(className.lastIndexOf('.')+1));
}
private final class ActivityOnClick implements View.OnClickListener
diff --git a/apps/SpareParts/res/values/strings.xml b/apps/SpareParts/res/values/strings.xml
index e157730..9e78be0 100644
--- a/apps/SpareParts/res/values/strings.xml
+++ b/apps/SpareParts/res/values/strings.xml
@@ -62,7 +62,7 @@
<!-- Sound & display settings screen, compatibility mode check box label -->
<string name="compatibility_mode_title">Compatibility Mode</string>
<!-- Sound & display settings screen, compatibility mode option summary text when check box is selected -->
- <string name="compatibility_mode_summary_on">Run older apps in Compatibility mode. This require rebooting. </string>
+ <string name="compatibility_mode_summary_on">Run older apps in Compatibility mode. This requires rebooting. </string>
<!-- Sound & display settings screen, compatibility mode option summary text when check box is clear -->
- <string name="compatibility_mode_summary_off">Run older apps in Compatibility mode. This require rebooting. </string>
+ <string name="compatibility_mode_summary_off">Run older apps in Compatibility mode. This requires rebooting. </string>
</resources>
diff --git a/apps/SpareParts/res/xml/spare_parts.xml b/apps/SpareParts/res/xml/spare_parts.xml
index 524092e..0d06e26 100644
--- a/apps/SpareParts/res/xml/spare_parts.xml
+++ b/apps/SpareParts/res/xml/spare_parts.xml
@@ -26,7 +26,7 @@
android:summary="@string/summary_battery_history">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
- android:targetClass="com.android.settings.battery_history.BatteryHistory" />
+ android:targetClass="com.android.settings.fuelgauge.PowerUsageSummary" />
</PreferenceScreen>
<PreferenceScreen android:key="battery_information_settings"
diff --git a/build/sdk.atree b/build/sdk.atree
index c2664cd..a8aa0c5 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -60,7 +60,7 @@
sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop
# the uper-jar file that apps link against. This is the public API
-out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
+${OUT_DIR}/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
# the aidl precompiled include
obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl
@@ -140,7 +140,7 @@
# samples to include in the sdk samples package
#
-# the list here should match the list of samples that we generate docs for,
+# the list here should match the list of samples that we generate docs for,
# (see web_docs_sample_code_flags in frameworks/base/Android.mk)
development/apps/GestureBuilder samples/${PLATFORM_NAME}/GestureBuilder
development/samples/source.properties samples/${PLATFORM_NAME}/source.properties
diff --git a/build/tools/make_windows_sdk.sh b/build/tools/make_windows_sdk.sh
deleted file mode 100755
index 1154452..0000000
--- a/build/tools/make_windows_sdk.sh
+++ /dev/null
@@ -1,258 +0,0 @@
-#!/bin/bash
-# Quick semi-auto file to build Windows SDK tools.
-#
-# Limitations and requirements:
-# - Expects the emulator has been built first, will pick it up from prebuilt.
-# - Run in Cygwin
-# - Expects to have one of the existing SDK (Darwin or Linux) to build the Windows one
-# - Needs Cygwin packages: autoconf, bison, curl, flex, gcc, g++, git,
-# gnupg, make, mingw-zlib, python, zip, unzip
-# - Must NOT have cygwin package readline (its GPL license might taint the SDK if
-# it gets compiled in)
-# - Does not need a Java Development Kit or any other tools outside of cygwin.
-# - If you think you may have Windows versions of tools (e.g. make) installed, it may
-# reduce confusion levels to 'export PATH=/usr/bin'
-
-PROG_NAME="$0"
-SDK_ZIP="$1"; shift
-DIST_DIR="$1"; shift
-TEMP_DIR="$1"; shift
-[ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp}
-
-set -e # Fail this script as soon as a command fails -- fail early, fail fast
-
-function die() {
- echo "Error:" $*
- echo "Aborting"
- exit 1
-}
-
-function usage() {
- local NAME
- NAME=`basename ${PROG_NAME}`
- echo "Usage: ${NAME} linux_or_mac_sdk.zip output_dir [temp_dir]"
- echo "If temp_dir is not given, \$TMP is used. If that's missing, /tmp is used."
- status
- exit 2
-}
-
-function status() {
- echo "Current values:"
- echo "- Input SDK: ${SDK_ZIP:-missing}"
- echo "- Output dir: ${DIST_DIR:-missing}"
- echo "- Temp dir: ${TEMP_DIR:-missing}"
-}
-
-function check() {
- [ -f "$SDK_ZIP" ] || usage
- [ -d "$DIST_DIR" ] || usage
-
-
- # We need mgwz.dll in the SDK when compiling with Cygwin 1.5
- # Right now we don't support building with Cygwin 1.7 yet, as it lacks this DLL.
- NEED_MGWZ=1
- # We can skip this check for debug purposes.
- echo $*
- [[ "$1" == "-no-mgwz" ]] && NEED_MGWZ=""
- CYG_MGWZ_PATH=/cygdrive/c/cygwin/bin/mgwz.dll
- [[ -n $NEED_MGWZ && ! -f $CYG_MGWZ_PATH ]] && \
- die "Cygwin is missing $CYG_MGWZ_PATH. Use -no-mgwz to override."
-
-
- # Use the BUILD_ID as SDK_NUMBER if defined, otherwise try to get it from the
- # provided zip filename.
- if [ -f config/build_id.make ]; then
- BUILD_ID=`cat config/build_id.make | sed -n '/BUILD_ID=/s/^[^=]\+=\(.*\)$/\1/p'`
- [ -n "$BUILD_ID" ] && SDK_NUMBER="$BUILD_ID"
- fi
- if [ -z "$SDK_NUMBER" ]; then
- # Look for a pattern like "anything_sdknumber.extension"
- # The pattern is now "any-thing_sdknumber_anything-else.extension"
- #
- # The bottom line is that the SDK number is whatever is enclosed by
- # the LAST couple of underscores. You can have underscores *before* the
- # SDK number if you want, but not after, e.g these are valid:
- # android_sdk_4242_platform.zip or blah_42_.zip
- #
- # Note that the root directory name in the zip must match the zip
- # name, too, so there's no point just changing the zip name to match
- # the above format.
- #
- # SDK_NUMBER will be empty if nothing matched.
- filename=`basename "$SDK_ZIP"`
- SDK_NUMBER=`echo $filename | sed -n 's/^.*_\([^_./]\+\)_[^_.]*\..*$/\1/p'`
- fi
-
- [ -n "$SDK_NUMBER" ] || die "Failed to extract the SDK number from $SDK_ZIP. Check its format."
-
- [ $OSTYPE == "cygwin" ] || die "This expects to run under Cygwin"
- [ -e `which zip` ] || die "Please install 'zip' package in Cygwin"
- [ -f "build/envsetup.sh" ] || die "Please run this from the 'android' directory"
-
- echo "Using SDK ${SDK_NUMBER}"
-}
-
-function build() {
-
- # IMPORTANT: For Cygwin to be able to build Android targets here,
- # you will generally need to edit build/core/main.mk and add directories
- # where Android.mk makefiles are to be found to the SDK_ONLY==true section.
-
- echo
- echo "Building..."
- [ -n "$MAKE_OPT" ] && echo "Make options: $MAKE_OPT"
-
- . build/envsetup.sh
-
- # Disable parallel build: it generates "permission denied" issues when
- # multiple "ar.exe" are running in parallel.
- make \
- aapt adb aidl \
- etc1tool \
- prebuilt \
- dexdump dmtracedump \
- fastboot \
- hprof-conv \
- mksdcard \
- sdklauncher sqlite3 \
- zipalign \
- || die "Build failed"
-
- # Fix permissions. Git/cygwin may not make this +x as needed.
- chmod +x prebuilt/windows/sdl/bin/sdl-config
-
- # It's worth building the emulator with -j 4 so do it separately
- make -j 4 emulator || die "Build failed"
-}
-
-function package() {
- echo
- echo "Packaging..."
- DEST_NAME="android-sdk_${SDK_NUMBER}_windows"
- DEST_NAME_ZIP="${DEST_NAME}.zip"
-
- TEMP_SDK_DIR="$TEMP_DIR/$DEST_NAME"
-
- # Unzip current linux/mac SDK and rename using the windows name
- [ -e "$TEMP_SDK_DIR" ] && rm -rfv "$TEMP_SDK_DIR" # cleanup dest first if exists
- UNZIPPED=`basename "$SDK_ZIP"`
- UNZIPPED="$TEMP_DIR/${UNZIPPED/.zip/}"
- [ -e "$UNZIPPED" ] && rm -rfv "$UNZIPPED" # cleanup unzip dir (if exists)
- unzip "$SDK_ZIP" -d "$TEMP_DIR"
- mv -v "$UNZIPPED" "$TEMP_SDK_DIR"
-
- # Assert that the package contains only one platform
- PLATFORMS="$TEMP_SDK_DIR/platforms"
- THE_PLATFORM=`echo $PLATFORMS/*`
- PLATFORM_TOOLS=$THE_PLATFORM/tools
- echo "Platform found: " $THE_PLATFORM
- [[ -d "$THE_PLATFORM" ]] || die \
- "Error: One platform was expected in $SDK_ZIP. " \
- "Instead found " $THE_PLATFORM
- [[ -d "$PLATFORM_TOOLS" ]] || die "Missing folder $PLATFORM_TOOLS."
-
- # Package USB Driver
- if type package_usb_driver 2>&1 | grep -q function ; then
- package_usb_driver $TEMP_SDK_DIR
- fi
-
- # Remove obsolete stuff from tools & platform
- TOOLS="$TEMP_SDK_DIR/tools"
- LIB="$TEMP_SDK_DIR/tools/lib"
- rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator,etc1tool}
- rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,layoutopt,mksdcard,sqlite3,traceview,zipalign}
- rm -v "$LIB"/*/swt.jar
- rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
-
- # Copy all the new stuff in tools
- # Note: some tools are first copied here and then moved in platforms/<name>/tools/
- cp -v out/host/windows-x86/bin/*.{exe,dll} "$TOOLS"/
- mkdir -pv "$LIB"/x86
- cp -v prebuilt/windows/swt/swt.jar "$LIB"/x86/
- mkdir -pv "$LIB"/x86_64
- cp -v prebuilt/windows-x86_64/swt/swt.jar "$LIB"/x86_64/
-
- # Copy the SDK Manager (aka sdklauncher) to the root of the SDK (it was copied in tools above)
- # and move it also in SDK/tools/lib (so that tools updates can update the root one too)
- cp "$TOOLS/sdklauncher.exe" "$TEMP_SDK_DIR/SDK Manager.exe"
- mv "$TOOLS/sdklauncher.exe" "$LIB/SDK Manager.exe"
-
- # If you want the emulator NOTICE in the tools dir, uncomment the following line:
- # cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
-
- # We currently need libz from MinGW for aapt
- [[ -n $NEED_MGWZ ]] && cp -v $CYG_MGWZ_PATH "$TOOLS"/
-
- # Update a bunch of bat files
- cp -v sdk/files/post_tools_install.bat "$LIB"/
- cp -v sdk/files/find_java.bat "$LIB"/
- cp -v sdk/apkbuilder/etc/apkbuilder.bat "$TOOLS"/
- cp -v sdk/ddms/app/etc/ddms.bat "$TOOLS"/
- cp -v sdk/traceview/etc/traceview.bat "$TOOLS"/
- cp -v sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat "$TOOLS"/
- cp -v sdk/layoutopt/app/etc/layoutopt.bat "$TOOLS"/
- cp -v sdk/draw9patch/etc/draw9patch.bat "$TOOLS"/
- cp -v sdk/sdkmanager/app/etc/android.bat "$TOOLS"/
-
- # Put the JetCreator tools, content and docs (not available in the linux SDK)
- JET="$TOOLS/Jet"
- JETCREATOR="$JET/JetCreator"
- JETDEMOCONTENT="$JET/demo_content"
- JETLOGICTEMPLATES="$JET/logic_templates"
- JETDOC="$TEMP_SDK_DIR/docs/JetCreator"
-
- # need to rm these folders since a Mac SDK will have them and it might create a conflict
- rm -rfv "$JET"
- rm -rfv "$JETDOC"
-
- # now create fresh folders for JetCreator
- mkdir -v "$JET"
- mkdir -v "$JETDOC"
-
- cp -rv external/sonivox/jet_tools/JetCreator "$JETCREATOR"/
- cp -rv external/sonivox/jet_tools/JetCreator_content "$JETDEMOCONTENT"/
- cp -rv external/sonivox/jet_tools/logic_templates "$JETLOGICTEMPLATES"/
- chmod -vR u+w "$JETCREATOR" # fixes an issue where Cygwin might copy the above as u+rx only
- cp -v prebuilt/windows/jetcreator/EASDLL.dll "$JETCREATOR"/
-
- cp -v external/sonivox/docs/JET_Authoring_Guidelines.html "$JETDOC"/
- cp -rv external/sonivox/docs/JET_Authoring_Guidelines_files "$JETDOC"/
- cp -v external/sonivox/docs/JET_Creator_User_Manual.html "$JETDOC"/
- cp -rv external/sonivox/docs/JET_Creator_User_Manual_files "$JETDOC"/
-
- # Copy or move platform specific tools to the default platform.
- cp -v dalvik/dx/etc/dx.bat "$PLATFORM_TOOLS"/
- mv -v "$TOOLS"/{aapt.exe,aidl.exe,dexdump.exe} "$PLATFORM_TOOLS"/
- # Note: mgwz.dll must be both in SDK/tools for zipalign and in SDK/platform/XYZ/tools/ for aapt
- [[ -n $NEED_MGWZ ]] && cp -v "$TOOLS"/mgwz.dll "$PLATFORM_TOOLS"/
-
- # Fix EOL chars to make window users happy - fix all files at the top level only
- # as well as all batch files including those in platforms/<name>/tools/
- find "$TEMP_SDK_DIR" -maxdepth 1 -type f -writable -print0 | xargs -0 unix2dos -D
- find "$TEMP_SDK_DIR" -maxdepth 3 -name "*.bat" -type f -writable -print0 | xargs -0 unix2dos -D
-
- # Done.. Zip it. Clean the temp folder ONLY if the zip worked (to ease debugging)
- pushd "$TEMP_DIR" > /dev/null
- [ -e "$DEST_NAME_ZIP" ] && rm -rfv "$DEST_NAME_ZIP"
- zip -9r "$DEST_NAME_ZIP" "$DEST_NAME" && rm -rfv "$DEST_NAME"
- popd > /dev/null
-
- # Now move the final zip from the temp dest to the final dist dir
- mv -v "$TEMP_DIR/$DEST_NAME_ZIP" "$DIST_DIR/$DEST_NAME_ZIP"
-
- # We want fastboot and adb (and its DLLs) next to the new SDK
- for i in fastboot.exe adb.exe AdbWinApi.dll AdbWinUsbApi.dll; do
- cp -vf out/host/windows-x86/bin/$i "$DIST_DIR"/$i
- done
-
- echo "Done"
- echo
- echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
-}
-
-check $*
-status
-build
-package
-
-echo "Done"
diff --git a/build/tools/patch_windows_sdk.sh b/build/tools/patch_windows_sdk.sh
index 14acdac..baaa173 100755
--- a/build/tools/patch_windows_sdk.sh
+++ b/build/tools/patch_windows_sdk.sh
@@ -5,7 +5,8 @@
# - development/tools/build/path_windows_sdk.sh to process the
# platform-dependent folders and files.
# - sdk/build/patch_windows_sdk.sh to process folder and files which
-# depend on the sdk.git repo. This file will be invoked by this one.
+# depend on the sdk.git repo. This file is invoked by the makefile
+# at development/tools/build/windows_sdk.mk.
#
# Input arguments:
# -q = Optional arg to make this silent. Must be given first.
@@ -16,26 +17,34 @@
# $3 = An optional replacement for $TOPDIR (inherited from the Android
# build system), which is the top directory where Android is located.
+set -e # any error stops the build
+
# Verbose by default. Use -q to make more silent.
-V="-v"
-if [[ "$1" == "-q" ]]; then V=""; shift; fi
+V=""
+Q=""
+if [[ "$1" == "-q" ]]; then
+ Q="$1"
+ shift
+else
+ echo "Win SDK: $0 $*"
+ set -x # show bash commands; no need for V=-v
+fi
TEMP_SDK_DIR=$1
WIN_OUT_DIR=$2
TOPDIR=${TOPDIR:-$3}
# The unix2dos is provided by the APT package "tofrodos". However
-# as of ubuntu lucid, the package renamed the command to "todos".
-UNIX2DOS=`which unix2dos`
+# as for ubuntu lucid, the package renamed the command to "todos".
+UNIX2DOS=$(which unix2dos || true)
if [[ ! -x $UNIX2DOS ]]; then
- UNIX2DOS=`which todos`
+ UNIX2DOS=$(which todos || true)
fi
PLATFORMS=( $TEMP_SDK_DIR/platforms/* )
if [[ ${#PLATFORMS[@]} != 1 ]]; then
echo "Error: Too many platforms found in $TEMP_SDK_DIR"
- echo "Only one was expected."
- echo "Instead, found: ${PLATFORMS[@]}"
+ echo "Expected one. Instead, found: ${PLATFORMS[@]}"
exit 1
fi
@@ -48,8 +57,7 @@
TOOLS=$TEMP_SDK_DIR/tools
PLATFORM_TOOLS=$TEMP_SDK_DIR/platform-tools
LIB=$TEMP_SDK_DIR/tools/lib
-rm $V $TOOLS/{android,apkbuilder,ddms,dmtracedump,draw9patch,emulator,etc1tool}
-rm $V $TOOLS/{hierarchyviewer,hprof-conv,layoutopt,mksdcard,sqlite3,traceview,zipalign}
+rm $V $TOOLS/{dmtracedump,etc1tool,hprof-conv,sqlite3,zipalign}
rm $V $LIB/*/swt.jar
rm $V $PLATFORM_TOOLS/{adb,aapt,aidl,dx,dexdump}
@@ -61,33 +69,6 @@
mkdir -pv $LIB/x86_64
cp $V ${TOPDIR}prebuilt/windows-x86_64/swt/swt.jar $LIB/x86_64/
-# Copy the SDK Manager (aka sdklauncher) to the root of the SDK (it was copied in tools above)
-# and move it also in SDK/tools/lib (so that tools updates can update the root one too)
-cp $TOOLS/sdklauncher.exe $TEMP_SDK_DIR/"SDK Manager.exe"
-mv $TOOLS/sdklauncher.exe $LIB/"SDK Manager.exe"
-
-# Copy the emulator NOTICE in the tools dir
-cp $V ${TOPDIR}external/qemu/NOTICE $TOOLS/emulator_NOTICE.txt
-
-# aapt under cygwin needs to have mgwz.dll
-[[ -n $NEED_MGWZ ]] && cp $V $CYG_MGWZ_PATH $TOOLS/
-
-# Update a bunch of bat files
-cp $V ${TOPDIR}sdk/files/post_tools_install.bat $LIB/
-cp $V ${TOPDIR}sdk/files/find_java.bat $LIB/
-cp $V ${TOPDIR}sdk/apkbuilder/etc/apkbuilder.bat $TOOLS/
-cp $V ${TOPDIR}sdk/ddms/app/etc/ddms.bat $TOOLS/
-cp $V ${TOPDIR}sdk/traceview/etc/traceview.bat $TOOLS/
-if [ -f ${TOPDIR}sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat ]; then
- cp $V ${TOPDIR}sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat $TOOLS/
-else
- # That's ok because currently GB uses Tools_r7 but we'll ship Tools_r8 from master-open.
- echo "WARNING: Ignoring ${TOPDIR}sdk/hierarchyviewer2/app/etc/hierarchyviewer.bat [ok for GB+Tools r8]"
-fi
-cp $V ${TOPDIR}sdk/layoutopt/app/etc/layoutopt.bat $TOOLS/
-cp $V ${TOPDIR}sdk/draw9patch/etc/draw9patch.bat $TOOLS/
-cp $V ${TOPDIR}sdk/sdkmanager/app/etc/android.bat $TOOLS/
-
# Put the JetCreator tools, content and docs (not available in the linux SDK)
JET=$TOOLS/Jet
JETCREATOR=$JET/JetCreator
@@ -118,10 +99,6 @@
cp $V ${TOPDIR}dalvik/dx/etc/dx.bat $PLATFORM_TOOLS/
mv $V $TOOLS/{adb.exe,aapt.exe,aidl.exe,dexdump.exe} $TOOLS/Adb*.dll $PLATFORM_TOOLS/
-# When building under cygwin, mgwz.dll must be both in SDK/tools for zipalign
-# and in SDK/platform/XYZ/tools/ for aapt
-[[ -n $NEED_MGWZ ]] && cp $V $TOOLS/mgwz.dll $PLATFORM_TOOLS/
-
# Fix EOL chars to make window users happy - fix all files at the top level
# as well as all batch files including those in platforms/<name>/tools/
if [[ -x $UNIX2DOS ]]; then
@@ -129,8 +106,8 @@
find $TEMP_SDK_DIR -maxdepth 3 -name "*.bat" -type f -print0 | xargs -0 $UNIX2DOS
fi
-# Just to make it easier on the build servers, we want fastboot and adb (and its DLLs)
-# next to the new SDK, so up one dir.
+# Just to make it easier on the build servers, we want fastboot and adb
+# (and its DLLs) next to the new SDK.
for i in fastboot.exe adb.exe AdbWinApi.dll AdbWinUsbApi.dll; do
cp -f $V $WIN_OUT_DIR/host/windows-x86/bin/$i $TEMP_SDK_DIR/../$i
done
diff --git a/build/tools/windows_sdk.mk b/build/tools/windows_sdk.mk
index eb5b53e..1f8bc45 100644
--- a/build/tools/windows_sdk.mk
+++ b/build/tools/windows_sdk.mk
@@ -22,16 +22,18 @@
$(error Need a unix2dos command. Please 'apt-get install tofrodos')
endif
+include $(TOPDIR)sdk/build/windows_sdk_tools.mk
+
WIN_TARGETS := \
aapt adb aidl \
- emulator etc1tool \
+ etc1tool \
dexdump dmtracedump \
fastboot \
hprof-conv \
- mksdcard \
prebuilt \
- sdklauncher sqlite3 \
- zipalign
+ sqlite3 \
+ zipalign \
+ $(WIN_SDK_TARGETS)
# MAIN_SDK_NAME/DIR is set in build/core/Makefile
WIN_SDK_NAME := $(subst $(HOST_OS)-$(HOST_ARCH),windows,$(MAIN_SDK_NAME))
@@ -60,7 +62,7 @@
winsdk-tools: acp
$(call winsdk-banner,Build Windows Tools)
- $(hide) USE_MINGW=1 USE_CCACHE="" $(MAKE) PRODUCT-$(TARGET_PRODUCT)-$(strip $(WIN_TARGETS))
+ $(hide) USE_MINGW=1 USE_CCACHE="" $(MAKE) PRODUCT-$(TARGET_PRODUCT)-$(strip $(WIN_TARGETS)) $(if $(hide),,showcommands)
$(WIN_SDK_ZIP): winsdk-tools sdk
$(call winsdk-banner,Build $(WIN_SDK_NAME))
@@ -69,8 +71,13 @@
$(hide) mkdir -p $(WIN_SDK_DIR)
$(hide) cp -rf $(MAIN_SDK_DIR)/$(MAIN_SDK_NAME) $(WIN_SDK_DIR)/$(WIN_SDK_NAME)
$(hide) USB_DRIVER_HOOK=$(USB_DRIVER_HOOK) \
- $(TOPDIR)development/build/tools/patch_windows_sdk.sh \
- $(subst @,-q,$(hide)) \
+ $(TOPDIR)development/build/tools/patch_windows_sdk.sh $(subst @,-q,$(hide)) \
+ $(WIN_SDK_DIR)/$(WIN_SDK_NAME) $(OUT_DIR) $(TOPDIR)
+ # TODO remove test once llvm-rs-cc is merged
+ $(hide) if [ -f $(WIN_SDK_DIR)/$(WIN_SDK_NAME)/platform-tools/llvm-rs-cc.exe ]; then \
+ strip --strip-all $(WIN_SDK_DIR)/$(WIN_SDK_NAME)/platform-tools/llvm-rs-cc.exe; \
+ fi
+ $(hide) $(TOPDIR)sdk/build/patch_windows_sdk.sh $(subst @,-q,$(hide)) \
$(WIN_SDK_DIR)/$(WIN_SDK_NAME) $(OUT_DIR) $(TOPDIR)
$(hide) ( \
cd $(WIN_SDK_DIR) && \
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index 68c9411..a1f3060 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -337,9 +337,9 @@
synchronized (Monkey.this) {
mAbort = true;
}
- return (mKillProcessAfterError) ? -1 : 1;
+ return (mKillProcessAfterError) ? -1 : 0;
}
- return 1;
+ return 0;
}
}
@@ -981,6 +981,9 @@
int eventCounter = 0;
int cycleCounter = 0;
+ boolean shouldReportAnrTraces = false;
+ boolean shouldReportDumpsysMemInfo = false;
+ boolean shouldAbort = false;
boolean systemCrashed = false;
// TO DO : The count should apply to each of the script file.
@@ -991,8 +994,8 @@
mRequestProcRank = false;
}
if (mRequestAnrTraces) {
- reportAnrTraces();
mRequestAnrTraces = false;
+ shouldReportAnrTraces = true;
}
if (mRequestAnrBugreport){
getBugreport("anr_" + mReportProcessName + "_");
@@ -1003,8 +1006,8 @@
mRequestAnrBugreport = false;
}
if (mRequestDumpsysMemInfo) {
- reportDumpsysMemInfo();
mRequestDumpsysMemInfo = false;
+ shouldReportDumpsysMemInfo = true;
}
if (mMonitorNativeCrashes) {
// first time through, when eventCounter == 0, just set up
@@ -1018,12 +1021,29 @@
}
}
if (mAbort) {
- System.out.println("** Monkey aborted due to error.");
- System.out.println("Events injected: " + eventCounter);
- return eventCounter;
+ shouldAbort = true;
}
}
+ // Report ANR, dumpsys after releasing lock on this.
+ // This ensures the availability of the lock to Activity controller's appNotResponding
+ if (shouldReportAnrTraces) {
+ shouldReportAnrTraces = false;
+ reportAnrTraces();
+ }
+
+ if (shouldReportDumpsysMemInfo) {
+ shouldReportDumpsysMemInfo = false;
+ reportDumpsysMemInfo();
+ }
+
+ if (shouldAbort) {
+ shouldAbort = false;
+ System.out.println("** Monkey aborted due to error.");
+ System.out.println("Events injected: " + eventCounter);
+ return eventCounter;
+ }
+
// In this debugging mode, we never send any events. This is
// primarily here so you can manually test the package or category
// limits, while manually exercising the system.
diff --git a/docs/howto_SDK_git_cygwin.txt b/docs/howto_SDK_git_cygwin.txt
deleted file mode 100644
index 622c592..0000000
--- a/docs/howto_SDK_git_cygwin.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-Copyright (C) 2009 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.
-
-
-Subject: How to get the android source code using Cygwin and Git
-Date: 2009/04/27
-Updated: 2009/05/21
-Updated: 2010/03/30
-
-
-Table of content:
- 1- Goals and Requirements
- 2- Getting the code, the simple way
- 3- SSH issues
- 4- Advanced Tricks
-
-
--------------------------
-1- Goals and Requirements
--------------------------
-
-This document explains how to checkout the Android source from the git
-repositories under Windows.
-
-As stated in development/docs/howto_build_SDK.txt, one can't build the whole
-Android source code under Windows. You can only build the SDK tools for
-Windows.
-
-There are a number of caveats in checking out the code from Git under Windows.
-This document tries to explain them.
-
-First you will need to meet the following requirements:
-- You must have Cygwin installed. But wait! You CANNOT use the latest Cygwin 1.7.
- Instead you MUST use the "legacy Cygwin 1.5" that you can find at this page:
-
- http://cygwin.org/win-9x.html
-
- Don't mind the page title, just grab setup-legacy.exe and it will works just fine
- under XP or Vista.
-
-- You must install Cyginw using the "Unix / Binary" mode.
- If you don't do that, git will fail to properly compute some SHA1 keys.
-
-- You need the "git" and "curl" packages to checkout the code.
- If you plan to contribute, you might want to get "gitk" also.
-
- Note: if you want to build the SDK, check the howto_build_SDK.txt file
- for a list of extra required packages.
- The short summary is that you need at least these:
- autoconf, bison, curl, flex, gcc, g++, git, gnupg, make, mingw-zlib, python, unzip, zip
- and you must avoid the "readline" package.
-
-
------------------------------------
-2- Getting the code, the simple way
------------------------------------
-
-Out of the box, "repo" and "git" will work just fine under Cygwin:
-
- $ repo init -u git://android.git.kernel.org/platform/manifest.git
- $ repo sync
-
-And you're done. You can build as explained in howto_build_SDK.txt and ignore
-the rest of this document.
-
-
--------------
-3- SSH issues
--------------
-
-If you maintain your own private repository using an SSH server, you might get
-some "mux/ssh" errors. In this case try this:
-
- $ repo init -u ssh://my.private.ssh.repo/platform/manifest.git
- $ export GIT_SSH=ssh
- $ repo sync
-
-
-------------------
-4- Advanced Tricks
-------------------
-
-There is one remaining issue with the default repo/git options:
-
-If you plan on contributing, you will notice that even after a fresh "repo
-sync" some projects are marked as having modified files. This happens on the
-"bionic" and the "external/iptables" project. The issue is that they have files
-which have the same name yet differ only by their case-sensitivity. Since the
-Windows filesystem is not case-sensitive, this confuses Git.
-
-Solution: we can simply ignore these projects as they are not needed to build
-the Windows SDK.
-
-To do this you just need to create a file .repo/local_manifest.xml that
-provides a list of projects to ignore:
-
-<?xml version="1.0" encoding="UTF-8"?>
-<manifest>
- <remove-project name="platform/external/iptables" />
-</manifest>
-
-The other thing we can do is tell git not to track the files that cause
-problems:
-
- cd bionic
- git update-index --assume-unchanged \
- libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
- libc/kernel/common/linux/netfilter/xt_MARK.h \
- libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
-
- cd external/tcpdump;
- git update-index --assume-unchanged \
- tests/print-X.new \
- tests/print-XX.new
-
-
-Here's a script that takes care of all these details. It performs the repo
-init, creates the appropriate local_manifest.xml, does a repo sync as
-needed and tell git to ignore the offending files:
-
-------------
-#!/bin/bash
-
-set -e # fail on errors
-
-URL=ssh://android-git.corp.google.com:29418/platform/manifest.git
-BRANCH=donut
-if [ "$1" == "-b" ]; then shift; BRANCH=$1; shift; fi
-
-# repo init if there's no .repo directory
-if [[ ! -d .repo ]]; then
- repo init -u $URL -b $BRANCH
-fi
-
-# create a local_manifest to exclude projects that cause problems under Windows
-# due to the case-insenstivines of the file system.
-L=.repo/local_manifest.xml
-if [[ ! -f $L ]]; then
-
- cat > $L <<EOF
-<?xml version="1.0" encoding="UTF-8"?>
-<manifest>
-<remove-project name="platform/external/iptables" />
-</manifest>
-EOF
-fi
-
-# sync using the native ssh client if necessary
-[[ $URL != ${URL/ssh/} ]] && export GIT_SSH=ssh
-repo sync $@
-
-
-# These files cause trouble too, we need to ignore them
-(cd bionic;
-git update-index --assume-unchanged \
- libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
- libc/kernel/common/linux/netfilter/xt_MARK.h \
- libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
-)
-(cd external/tcpdump;
-git update-index --assume-unchanged \
- tests/print-X.new \
- tests/print-XX.new
-)
-------------
-
-Simply extract this to a "my_sync.sh" file and try the following:
- $ mkdir android_src
- $ cd android_src
- $ chmod +x mysync.sh
- $ ./mysync.sh
-
-
--end-
-
-
-
-
diff --git a/docs/howto_build_SDK.txt b/docs/howto_build_SDK.txt
deleted file mode 100644
index e09440b..0000000
--- a/docs/howto_build_SDK.txt
+++ /dev/null
@@ -1,305 +0,0 @@
-Copyright (C) 2009 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.
-
-
-Subject: How to build an Android SDK & ADT Eclipse plugin.
-Date: 2009/03/27
-Updated: 2010/03/30
-
-
-Table of content:
- 0- License
- 1- Foreword
- 2- Building an SDK for MacOS and Linux
- 3- Building an SDK for Windows
- 4- Building an ADT plugin for Eclipse
- 5- Conclusion
-
-
-
-----------
-0- License
-----------
-
- Copyright (C) 2009 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.
-
-
-
------------
-1- Foreword
------------
-
-This document explains how to build the Android SDK and the ADT Eclipse plugin.
-
-It is designed for advanced users which are proficient with command-line
-operations and know how to setup the pre-required software.
-
-Basically it's not trivial yet when done right it's not that complicated.
-
-
-
---------------------------------------
-2- Building an SDK for MacOS and Linux
---------------------------------------
-
-First, setup your development environment and get the Android source code from
-git as explained here:
-
- http://source.android.com/download
-
-For example for the cupcake branch:
-
- $ mkdir ~/my-android-git
- $ cd ~/my-android-git
- $ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake
- $ repo sync
-
-Then once you have all the source, simply build the SDK using:
-
- $ cd ~/my-android-git
- $ . build/envsetup.sh
- $ lunch sdk-eng
- $ make sdk
-
-This will take a while, maybe between 20 minutes and several hours depending on
-your machine. After a while you'll see this in the output:
-
- Package SDK: out/host/darwin-x86/sdk/android-sdk_eng.<build-id>_mac-x86.zip
-
-Some options:
-
-- Depending on your machine you can tell 'make' to build more things in
- parallel, e.g. if you have a dual core, use "make -j4 sdk" to build faster.
-
-- You can define "BUILD_NUMBER" to control the build identifier that gets
- incorporated in the resulting archive. The default is to use your username.
- One suggestion is to include the date, e.g.:
-
- $ export BUILD_NUMBER=${USER}-`date +%Y%m%d-%H%M%S`
-
- There are certain characters you should avoid in the build number, typically
- everything that might confuse 'make' or your shell. So for example avoid
- punctuation and characters like $ & : / \ < > , and .
-
-
-
-------------------------------
-3- Building an SDK for Windows
-------------------------------
-
-A- SDK pre-requisite
---------------------
-
-First you need to build an SDK for MacOS and Linux. The Windows build works by
-updating an existing MacOS or Linux SDK zip file and replacing the unix
-binaries by Windows binaries.
-
-
-
-B- Cygwin pre-requisite & code checkout
----------------------------------------
-
-You must have Cygwin installed. But wait! You CANNOT use the latest Cygwin 1.7.
-Instead you MUST use the "legacy Cygwin 1.5" that you can find at this page:
-
- http://cygwin.org/win-9x.html
-
-Don't mind the page title, just grab setup-legacy.exe and it will works just fine
-under XP or Vista.
-
-
-Now configure it:
-- When installing Cygwin, set Default Text File Type to Unix/binary, not DOS/text.
- This is really important, otherwise you will get errors when trying to
- checkout code using git.
-- Packages that you must install or not:
- - Required packages: autoconf, bison, curl, flex, gcc, g++, git, gnupg, make,
- mingw-zlib, python, zip, unzip.
- - Suggested extra packages: diffutils, emacs, openssh, rsync, vim, wget.
- - Packages that must not be installed: readline.
-
-Once you installed Cygwin properly, checkout the code from git as you did
-for MacOS or Linux. Make sure to get the same branch, and if possible keep
-it as close to the other one as possible:
-
- $ mkdir ~/my-android-git
- $ cd ~/my-android-git
- $ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake
- $ repo sync
-
-
-
-C- Building the Windows SDK
----------------------------
-
-Now it's time to build that Windows SDK. You need:
-- The path to the MacOS or Linux SDK zip.
-- A directory where to place the final SDK. It will also hold some temporary
- files.
-- The build number will be extracted from the SDK zip filename, but this will
- only work if that build number has no underscores in it. It is suggested you
- just define SDK_NUMBER (and not BUILD_NUMBER!) on the command line before
- invoking the script.
-
- Note that the "SDK number" is really a free identifier of your choice. It
- doesn't need to be strictly a number. As always it is suggested you avoid
- too much punctuation and special shell/make characters. Underscores cannot
- be used.
-
-
-To summarize, the steps on the command line would be something like this:
-
- $ mkdir ~/mysdk
- $ export SDK_NUMBER=${USER}-`date +%Y%m%d-%H%M%S`
- $ cd ~/my-android-git
- $ development/build/tools/make_windows_sdk.sh /path/to/macos/or/linux/sdk.zip ~/mysdk
-
-This will take a while to build some Windows-specific binaries, including the
-emulator, unzip the previous zip, rename & replace things and rezip the final
-Windows SDK zip file. A typical build time should be around 5-10 minutes.
-
-
-
--------------------------------------
-4- Building an ADT plugin for Eclipse
--------------------------------------
-
-Requirements:
-- You can currently only build an ADT plugin for Eclipse under Linux.
-- You must have a working version of Eclipse 3.4 "ganymede" RCP installed.
-- You need X11 to run Eclipse at least once.
-- You need a lot of patience. The trick is to do the initial setup correctly
- once, after it's a piece of cake.
-
-
-
-A- Pre-requisites
------------------
-
-Note for Ubuntu or Debian users: your apt repository probably only has Eclipse
-3.2 available and it's probably not suitable to build plugins in the first
-place. Forget that and install a working 3.4 manually as described below.
-
-- Visit http://www.eclipse.org/downloads/ to grab the
- "Eclipse for RCP/Plug-in Developers (176 MB)" download for Linux.
- 32-bit and 64-bit versions are available, depending on your Linux installation.
-
- Note: we've always used a 32-bit one, so use the 64-bit one at your own risk.
-
- Note: Eclipse comes in various editions. Do yourself a favor and just stick
- to the RCP for building this plugin. For example the J2EE contains too many
- useless features that will get in the way, and the "Java" version lacks some
- plugins you need to build other plugins. Please just use the RCP one.
-
-- Unpack "eclipse-rcp-ganymede-SR2-linux-gtk.tar.gz" in the directory of
- your choice, e.g.:
-
- $ mkdir ~/eclipse-3.4
- $ cd ~/eclipse-3.4
- $ tar xvzf eclipse-rcp-ganymede-SR2-linux-gtk.tar.gz
-
- This will create an "eclipse" directory in the current directory.
-
-- Set ECLIPSE_HOME to that "eclipse" directory:
-
- $ export ECLIPSE_HOME=~/eclipse-3.4/eclipse
-
- Note: it is important you set ECLIPSE_HOME before starting the build.
- Otherwise the build process will try to download and install its own Eclipse
- installation in /buildroot, which is probably limited to root.
-
-- Now, before you can build anything, it is important that you start Eclipse
- *manually* once using the same user that you will use to build later. That's
- because your Eclipse installation is not finished: Eclipse must be run at
- least once to create some files in ~/.eclipse/. So run Eclipse now:
-
- $ ~/eclipse-3.4/eclipse/eclipse &
-
- Wait for it load, create a workspace when requested and then simply quit
- using the File > Quit menu. That's it. You won't need to run it manually
- again.
-
-
-
-B- Building ADT
----------------
-
-Finally, you have Eclipse, it's installed and it created its own config files,
-so now you can build your ADT plugin. To do that you'll change directories to
-your git repository and invoke the build script by giving it a destination
-directory and an optional build number:
-
- $ mkdir ~/mysdk
- $ cd ~/my-android-git # <-- this is where you did your "repo sync"
- $ development/tools/eclipse/scripts/build_server.sh ~/mysdk $USER
-
-The first argument is the destination directory. It must be absolute. Do not
-give a relative destination directory such as "../mysdk". This will make the
-Eclipse build fail with a cryptic message:
-
- BUILD SUCCESSFUL
- Total time: 1 minute 5 seconds
- **** Package in ../mysdk
- Error: Build failed to produce ../mysdk/android-eclipse
- Aborting
-
-The second argument is the build "number". The example used "$USER" but it
-really is a free identifier of your choice. It cannot contain spaces nor
-periods (dashes are ok.) If the build number is missing, a build timestamp will
-be used instead in the filename.
-
-The build should take something like 5-10 minutes.
-
-
-When the build succeeds, you'll see something like this at the end of the
-output:
-
- ZIP of Update site available at ~/mysdk/android-eclipse-v200903272328.zip
-or
- ZIP of Update site available at ~/mysdk/android-eclipse-<buildnumber>.zip
-
-When you load the plugin in Eclipse, its feature and plugin name will look like
-"com.android.ide.eclipse.adt_0.9.0.v200903272328-<buildnumber>.jar". The
-internal plugin ID is always composed of the package, the build timestamp and
-then your own build identifier (a.k.a. the "build number"), if provided. This
-means successive builds with the same build identifier are incremental and
-Eclipse will know how to update to more recent ones.
-
-
-
--------------
-5- Conclusion
--------------
-
-This completes the howto guide on building your own SDK and ADT plugin.
-Feedback is welcome on the public Android Open Source forums:
- http://source.android.com/discuss
-
-If you are upgrading from a pre-cupcake to a cupcake or later SDK please read
-the accompanying document "howto_use_cupcake_sdk.txt".
-
--end-
-
diff --git a/docs/howto_use_cupcake_sdk.txt b/docs/howto_use_cupcake_sdk.txt
deleted file mode 100644
index b131230..0000000
--- a/docs/howto_use_cupcake_sdk.txt
+++ /dev/null
@@ -1,371 +0,0 @@
-Subject: How to build use a Cupcake Android SDK & ADT Eclipse plugin.
-Date: 2009/03/27
-
-
-Table of content:
- 0- License
- 1- Foreword
- 2- Installation steps
- 3- For Eclipse users
- 4- For Ant users
- 5- Targets, AVDs, Emulator changes
- 6- Conclusion
-
-
-
-----------
-0- License
-----------
-
- Copyright (C) 2009 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.
-
-
-
------------
-1- Foreword
------------
-
-This explains how to use the "new" SDK provided starting with cupcake.
-The new SDK has as a different structure than the pre-cupcake ones.
-
-This means:
-- The new SDK does not work with older Eclipse plugins (ADT 0.8)
-- The old SDKs (1.0 and 1.1) do NOT work with this Eclipse plugin (ADT 0.9)
-
-
-
-----------------------
-2- Installation steps
-----------------------
-
-First you will need to grab the zip of the SDK for your platform or build it
-yourself. Please refer to the accompanying document "howto_build_SDK.txt" if
-needed.
-
-Unzip the SDK somewhere. We'll call that directory "SDK" in command-line
-examples.
-
-Grab the new ADT Eclipse plugin zip file or build it yourself. Keep it
-somewhere (no need to unzip).
-
-
-
---------------------
-3- For Eclipse users
---------------------
-
-
-Below we'll explain how you can upgrade your Eclipse install to the new plugin.
-If you already have a working Eclipse installation with a pre-0.9 ADT,
-another suggestion is to simply install a new copy of Eclipse and create a
-new empty workspace. This is just a precaution. The update process should
-be otherwise harmless.
-
-
-
-A- Setting up Eclipse
----------------------
-
-- You must have Eclipse 3.3 or 3.4. Eclipse 3.2 is not longer supported.
-
- There are many flavors, or "editions", of Eclipse. To develop, we'd recommend
- the "Java" edition. The "RCP" one is totally suitable too. The J2EE one is
- probably overkill.
-
-
-- If updating an existing Eclipse, use Help > Software Update and please
- uninstall the two features of the previous ADT: the "editors" feature and the
- ADT feature itself.
-
- => If you don't you will get a conflict on editors when installing
- the new one.
-
-- Using Help > Software Update, add a new "archived site", point it to the new
- adt.zip (e.g. android-eclipse-<some-id>.zip), select the "Install" button at
- the top right and restart eclipse as needed.
-
-- After it restarts, please use Window > Preferences > Android and select
- the new SDK folder that you unzipped in paragraph 2.
-
-
-
-B- Updating older projects
---------------------------
-
-If you have pre-0.9 projects in your Eclipse workspace, or if you import them
-from your code repository, these projects will fail to build at first.
-
-First right-click on the project and select "Properties":
-
-- In the properties, open the Android panel and select the platform to use.
- The SDK comes with a 1.5 platform. Select it and close the properties panel.
-- Do a clean build.
-
-
-The new plugin creates a "gen" folder in your project where it puts the R.java
-and all automatically generated AIDL java files. If you get an error such as:
-
- "The type R is already defined"
-
-that means you must check to see if your old R.java or your old auto-generated
-AIDL Java files are still present in the "src" folder. If yes, remove them.
-
-Note: this does not apply to your own hand-crafted parcelable AIDL java files.
-
-Note: if you want to reuse the project with an older Eclipse ADT install,
- simply remove the "gen" folder from the build path of the project.
-
-
-C- New Wizards
---------------
-
-The "New Android Project" wizard has been expanded to use the multi-platform
-capabilities of the new SDK.
-
-There is now a "New XML File" wizard that lets you create skeleton XML resource
-files for your Android projects. This makes it easier to create a new layout, a
-new strings file, etc.
-
-Both wizard are available via File > New... as well as new icons in the main
-icon bar. If you do not see the new icons, you may need to use Window > Reset
-Perspective on your Java perspective.
-
-
-Please see step 5 "Emulator changes" below for important details on how to run
-the emulator.
-
-
-
-----------------
-4- For Ant users
-----------------
-
-
-A- build.xml has changed
-------------------------
-
-You must re-create your build.xml file.
-
-First if you had customized your build.xml, make a copy of it:
-
- $ cd my-project
- $ cp build.xml build.xml.old
-
-
-Then use the new "android" tool to create a new build.xml:
-
- $ SDK/tools/android update project --path /path/to/my-project
-
-or
-
- $ cd my-project
- $ SDK/tools/android update project --path .
-
-
-A "gen" folder will be created the first time you build and your R.java and
-your AIDL Java files will be generated in this "gen" folder. You MUST remove
-the old R.java and old auto-generated AIDL java files manually. (Note: this
-does not apply to your own hand-crafted parcelabe AIDL java files.)
-
-
-B- Where is activitycreator?
-----------------------------
-
-Note that the "activitycreator" tool has been replaced by the new "android"
-tool too. Example of how to create a new Ant project:
-
- $ SDK/tools/android create project --path /path/to/my/project --name ProjectName
- --package com.mycompany.myapp --activity MyActivityClass
- --target 1 --mode activity
-
-
-Please see paragraph 5 below for important details on how to run the emulator
-and the meaning of that "--target 1" parameter.
-
-
-
-----------------------------------
-5- Targets, AVDs, Emulator changes
-----------------------------------
-
-This applies to BOTH Eclipse and Ant users.
-
-One major change with the emulator is that now you must pre-create an "Android
-Virtual Device" (a.k.a "AVD") before you run the emulator.
-
-
-
-A- What is an AVD and why do I need one?
-----------------------------------------
-
-What is an "AVD"? If you forget, just run:
-
- $ SDK/tools/emulator -help-virtual-device
-
- An Android Virtual Device (AVD) models a single virtual device running the
- Android platform that has, at least, its own kernel, system image and data
- partition.
-
-There is a lot more explanation given by the emulator. Please run the help
-command given above to read the rest.
-
-The bottom line is that you can create many emulator configurations, or "AVDs",
-each with their own system image and most important each with their own user
-data and SD card data. Then you tell Eclipse or the emulator which one to use
-to debug or run your applications.
-
-
-Note for Eclipse users: eventually there will be a user interface to do all of
-these operations. For right now, please use the command line interface.
-
-
-B- Listing targets and AVDs
----------------------------
-
-There is a new tool called "android" in the SDK that lets you know which
-"target" and AVDs you can use.
-
-A target is a specific version of Android that you can use. By default the SDK
-comes with an "Android 1.5" target, codenamed "cupcake". In the future there
-will be more versions of Android to use, e.g. "Android 2.0" or specific add-ons
-provided by hardware manufacturers. When you want to run an emulator, you need
-to specify a given flavor of Android: this is the "target".
-
-
-To learn about available targets in your SDK, use this command:
-
- $ SDK/tools/android list targets
-
-This will give you an output such as:
-
- Available Android targets:
- [1] Android 1.5
- API level: 3
- Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
-
-Note the "[1]". Later you will need to reference this as "--target 1" on the
-command line.
-
-
-Similarly you can list the available AVDs:
-
- $ SDK/tools/android list avds
-
-Which might output something as:
-
- Available Android Virtual Devices:
- Name: my_avd
- Path: C:\Users\<username>\.android\avd\my_avd.avd
- Target: Android 1.5 (API level 3)
- Skin: 320x480
- Sdcard: 16M
-
-
-
-C- Creating an AVD
-------------------
-
-To create a configuration:
-
- $ SDK/tools/android create avd --name my_avd_name --target 1
-
-
-where "target 1" is the index of a target listed by "android list targets".
-
-The AVD name is purely an identifier used to refer to the AVD later.
-Since it is used as directory name, please avoid using shell or path specific
-characters.
-
-To learn the various options available when creating an AVD, simply type:
-
- $ SDK/tools/android create avd
-
-The android tool will automatically print an explanation of required arguments.
-
-
-
-D- Invoking an AVD from the command-line
-----------------------------------------
-
-To use this AVD in the emulator from the command-line, type:
-
- $ SDK/tools/emulator @my_avd_name
-
-
-For more options, please consult the emulator help:
-
- $ SDK/tools/emulator -help-virtual-device
-
-
-
-E- Invoking an AVD from Eclipse
--------------------------------
-
-By default Android projects in Eclipse have an "automatic target" mode.
-In this mode, when a project is deployed in debug or run, it checks:
-- If there's one running device or emulator, this is used for deployment.
-- If there's more than one running device or emulator, a "device chooser" is
- shown to let the user select which one to use.
-- If there are no running devices or emulators, ADT looks at available AVDs.
- If one matches the project configuration (e.g. same API level), it is
- automatically used.
-
-Alternatively you can edit the "launch configuration" on your Android project
-in Eclipse by selecting the menu Run > Run Configurations. In the "target" tab
-of the configuration, you can choose:
-
-- Manual or automatic targetting mode.
-
- - Manual means to always present the device chooser.
- - Automatic is the behavior explained above.
-
-- In automatic mode, which AVD is preferred. If none is selected, the first
- suitable is used.
-
-
-F- AVD concurrency
-------------------
-
-You can no longer run several emulators at the same time on the same
-configuration.
-
-Before this used to put the second or more emulators in a transient read-only
-mode that would not save user data.
-
-Now you just need to create as many AVDs as you want to run emulators.
-
-For example if you are working on a client/server application for Android, you
-could create a "client" AVD and a "server" AVD then run them both at once. The
-emulator window will show you the AVD name so that you know which one is which.
-
-Example:
-
- $ SDK/tools/android create avd --name client --target 1 --sdcard 16M --skin HVGA
- $ SDK/tools/android create avd --name server --target 1 --sdcard 32M --skin HVGA-P
- $ SDK/tools/emulator @server &
- $ SDK/tools/emulator @client &
-
-
-
--------------
-6- Conclusion
--------------
-
-This completes the howto guide on how to use the new Cupcake SDK.
-Feedback is welcome on the public Android Open Source forums:
- http://source.android.com/discuss
-
--end-
-
diff --git a/host/windows/usb/android_winusb.inf b/host/windows/usb/android_winusb.inf
index b2daf89..47cf2f7 100755
--- a/host/windows/usb/android_winusb.inf
+++ b/host/windows/usb/android_winusb.inf
@@ -6,7 +6,7 @@
Class = AndroidUsbDeviceClass
ClassGuid = {3F966BD9-FA04-4ec5-991C-D326973B5128}
Provider = %ProviderName%
-DriverVer = 08/11/2009,2.0.0010.00002
+DriverVer = 12/06/2010,4.0.0000.00000
CatalogFile.NTx86 = androidwinusb86.cat
CatalogFile.NTamd64 = androidwinusba64.cat
@@ -38,14 +38,11 @@
%CompositeAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB&MI_01
;
;Google NexusOne
-%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02
+%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01
-%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11
-%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
+%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11
+%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E22&MI_01
-;
-; Dell's Mini5
-%CompositeAdbInterface% = USB_Install, USB\VID_413C&PID_B007&MI_01
[Google.NTamd64]
; HTC Dream
@@ -61,13 +58,10 @@
;
;Google NexusOne
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02
-%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01
+%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11
-%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
+%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E22&MI_01
-;
-; Dell's Mini5
-%CompositeAdbInterface% = USB_Install, USB\VID_413C&PID_B007&MI_01
[USB_Install]
Include = winusb.inf
@@ -88,7 +82,7 @@
KmdfService = WINUSB, WinUSB_Install
[WinUSB_Install]
-KmdfLibraryVersion = 1.7
+KmdfLibraryVersion = 1.9
[USB_Install.HW]
AddReg = Dev_AddReg
@@ -101,11 +95,11 @@
CopyFiles = CoInstallers_CopyFiles
[CoInstallers_AddReg]
-HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01007.dll,WdfCoInstaller","WinUSBCoInstaller.dll"
+HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll"
[CoInstallers_CopyFiles]
-WinUSBCoInstaller.dll
-WdfCoInstaller01007.dll
+WinUSBCoInstaller2.dll
+WdfCoInstaller01009.dll
[DestinationDirs]
CoInstallers_CopyFiles=11
@@ -115,12 +109,12 @@
2 = %DISK_NAME%,,,\amd64
[SourceDisksFiles.x86]
-WinUSBCoInstaller.dll = 1
-WdfCoInstaller01007.dll = 1
+WinUSBCoInstaller2.dll = 1
+WdfCoInstaller01009.dll = 1
[SourceDisksFiles.amd64]
-WinUSBCoInstaller.dll = 2
-WdfCoInstaller01007.dll = 2
+WinUSBCoInstaller2.dll = 2
+WdfCoInstaller01009.dll = 2
[Strings]
ProviderName = "Google, Inc."
diff --git a/host/windows/usb/legacy/driver/android_usb.inf b/host/windows/usb/legacy/driver/android_usb.inf
deleted file mode 100755
index f8bbf9a..0000000
--- a/host/windows/usb/legacy/driver/android_usb.inf
+++ /dev/null
@@ -1,130 +0,0 @@
-;/*++
-;
-;Abstract:
-; Installation inf for the Android USB Bulk device
-;
-;--*/
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=USB
-ClassGuid={F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}
-Provider=%GOOG%
-DriverVer=06/25/2009,1.0.0010.00001
-CatalogFile.NTx86=androidusb86.cat
-CatalogFile.NTamd64=androidusba64.cat
-
-; ================= Class section =====================
-
-[ClassInstall32]
-Addreg=AndroidUsbClassReg
-
-[AndroidUsbClassReg]
-HKR,,,0,%ClassName%
-HKR,,Icon,,-5
-
-[DestinationDirs]
-DefaultDestDir = 12
-
-; ================= Device section =====================
-
-[Manufacturer]
-%MfgName%=Google,NTx86,NTamd64
-
-; For Win2K
-[Google]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C03&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For XP and later
-[Google.NTx86]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C03&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For AMD64 and later
-[Google.NTamd64]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C03&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-[androidusb.Dev.NT]
-CopyFiles=androidusb.Files.Ext
-
-[androidusb.Dev.NT.Services]
-Addservice = androidusb, 0x00000002, androidusb.AddService
-
-[androidusb.AddService]
-DisplayName = %androidusb.SvcDesc%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %10%\System32\Drivers\androidusb.sys
-AddReg = androidusb.AddReg
-LoadOrderGroup = Base
-
-[androidusb.AddReg]
-HKR,"Parameters","MaximumTransferSize",0x10001,4096
-HKR,"Parameters","DebugLevel",0x10001,2
-HKR, Parameters\Wdf, VerboseOn, 0x00010001, 1
-HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
-HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
-
-[androidusb.Files.Ext]
-androidusb.sys
-
-[SourceDisksNames]
-1=%Disk_Description%,,,
-
-[SourceDisksFiles]
-androidusb.sys = 1
-
-;-------------- WDF Coinstaller installation
-[DestinationDirs]
-CoInstaller_CopyFiles = 11
-
-[androidusb.Dev.NT.CoInstallers]
-AddReg=CoInstaller_AddReg
-CopyFiles=CoInstaller_CopyFiles
-
-[CoInstaller_CopyFiles]
-wdfcoinstaller01005.dll
-
-[SourceDisksFiles]
-wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames
-
-[CoInstaller_AddReg]
-HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01005.dll,WdfCoInstaller"
-
-[androidusb.Dev.NT.Wdf]
-KmdfService = androidusb, androidusb_wdfsect
-
-[androidusb_wdfsect]
-KmdfLibraryVersion = 1.5
-
-;---------------------------------------------------------------;
-
-[Strings]
-GOOG = "Google, Inc"
-MfgName = "Google, Inc"
-Disk_Description= "ADB Interface Installation Disk"
-androidusb.SvcDesc = "ADB Interface Driver"
-ClassName = "ADB Interface"
-USB\VID_18D1&PID_DDDD.DeviceDescTest="ADB Testing Interface"
-USB\VID_0BB4&PID_0C01.DeviceDescRelease="HTC Dream"
-USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease="HTC Dream Composite ADB Interface"
-USB\VID_0BB4&PID_0C03&MI_01.DeviceDescRelease="HTC Magic Composite ADB Interface"
-USB\VID_0BB4&PID_0FFF.DeviceDescRelease="HTC Bootloader"
diff --git a/host/windows/usb/legacy/driver/android_usb.rc b/host/windows/usb/legacy/driver/android_usb.rc
deleted file mode 100755
index 0e7571e..0000000
--- a/host/windows/usb/legacy/driver/android_usb.rc
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-#include <windows.h>
-
-// Don't let the resource editor in here
-#ifdef APSTUDIO_INVOKED
- #error this file is not editable by Visual C++
-#endif //APSTUDIO_INVOKED
-
-
-#define VER_FILETYPE VFT_DRV
-#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
-#define VER_FILEDESCRIPTION_STR "ADB Interface"
-#define VER_INTERNALNAME_STR "androidusb.sys"
-#define VER_ORIGINALFILENAME_STR "androidusb.sys"
-#define VER_FILEOS VOS_NT
-#define VER_FILEFLAGSMASK (VS_FF_DEBUG | VS_FF_PRERELEASE)
-
-#if DBG
- #define VER_FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE
-#else // DBG
- #define VER_FILEFLAGS VS_FF_PRERELEASE
-#endif // DBG
-
-#include "common.ver"
diff --git a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_bulk_file_object.cpp
deleted file mode 100755
index 9f8ac6b..0000000
--- a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbBulkPipeFileObject
- that encapsulates extension to a bulk pipe file objects.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_bulk_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbBulkPipeFileObject::AndroidUsbBulkPipeFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj)
- : AndroidUsbPipeFileObject(dev_obj, wdf_fo, wdf_pipe_obj) {
- ASSERT_IRQL_PASSIVE();
-
-#if DBG
- WDF_USB_PIPE_INFORMATION pipe_info;
- WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
- WdfUsbTargetPipeGetInformation(wdf_pipe_obj, &pipe_info);
- ASSERT(WdfUsbPipeTypeBulk == pipe_info.PipeType);
-#endif // DBG
-}
-
-#pragma code_seg()
-
-AndroidUsbBulkPipeFileObject::~AndroidUsbBulkPipeFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.h b/host/windows/usb/legacy/driver/android_usb_bulk_file_object.h
deleted file mode 100755
index f563daa..0000000
--- a/host/windows/usb/legacy/driver/android_usb_bulk_file_object.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
-#define ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbBulkPipeFileObject
- that encapsulates extension to a bulk pipe file objects.
-*/
-
-#include "android_usb_pipe_file_object.h"
-
-/** AndroidUsbBulkPipeFileObject class encapsulates extension to a KMDF file
- object that represent opened bulk pipe. Instances of this class must be
- allocated from NonPagedPool.
-*/
-class AndroidUsbBulkPipeFileObject : public AndroidUsbPipeFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- @param wdf_pipe_obj[in] KMDF pipe for this file
- */
- AndroidUsbBulkPipeFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbBulkPipeFileObject();
-};
-
-#endif // ANDROID_USB_BULK_PIPE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_device_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_device_file_object.cpp
deleted file mode 100755
index a5e764e..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_file_object.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbDeviceFileObject
- that encapsulates an extension for a KMDF file object that represent
- opened device.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_device_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbDeviceFileObject::AndroidUsbDeviceFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo)
- : AndroidUsbFileObject(AndroidUsbFileObjectTypeDevice, dev_obj, wdf_fo) {
- ASSERT_IRQL_PASSIVE();
-}
-
-#pragma code_seg()
-
-AndroidUsbDeviceFileObject::~AndroidUsbDeviceFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-void AndroidUsbDeviceFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- switch (ioctl_code) {
- case ADB_IOCTL_GET_USB_DEVICE_DESCRIPTOR:
- device_object()->OnGetUsbDeviceDescriptorCtl(request, output_buf_len);
- break;
-
- case ADB_IOCTL_GET_USB_CONFIGURATION_DESCRIPTOR:
- device_object()->OnGetUsbConfigDescriptorCtl(request, output_buf_len);
- break;
-
- case ADB_IOCTL_GET_USB_INTERFACE_DESCRIPTOR:
- device_object()->OnGetUsbInterfaceDescriptorCtl(request, output_buf_len);
- break;
-
- case ADB_IOCTL_GET_ENDPOINT_INFORMATION:
- device_object()->OnGetEndpointInformationCtl(request,
- input_buf_len,
- output_buf_len);
- break;
-
- case ADB_IOCTL_GET_SERIAL_NUMBER:
- device_object()->OnGetSerialNumberCtl(request, output_buf_len);
- break;
-
- default:
- AndroidUsbFileObject::OnEvtIoDeviceControl(request,
- output_buf_len,
- input_buf_len,
- ioctl_code);
- break;
- }
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_device_file_object.h b/host/windows/usb/legacy/driver/android_usb_device_file_object.h
deleted file mode 100755
index 6deed6c..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_file_object.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_DEVICE_FILE_OBJECT_H__
-#define ANDROID_USB_DEVICE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbDeviceFileObject that
- encapsulates an extension for a KMDF file object that represent opened
- device.
-*/
-
-#include "android_usb_file_object.h"
-
-/** AndroidUsbDeviceFileObject class encapsulates an extension for a KMDF
- file object that represent opened device. Instances of this class must be
- allocated from NonPagedPool.
-*/
-class AndroidUsbDeviceFileObject : public AndroidUsbFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- */
- AndroidUsbDeviceFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbDeviceFileObject();
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to the file
- object this extension wraps. We override this method to handle the
- following IOCTL requests:
- 1. ADB_CTL_GET_USB_DEVICE_DESCRIPTOR
- 2. ADB_CTL_GET_USB_CONFIGURATION_DESCRIPTOR
- 3. ADB_CTL_GET_USB_INTERFACE_DESCRIPTOR
- 4. ADB_CTL_GET_ENDPOINT_INFORMATION
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-};
-
-#endif // ANDROID_USB_DEVICE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_device_object.cpp b/host/windows/usb/legacy/driver/android_usb_device_object.cpp
deleted file mode 100755
index 1e7101f..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_object.cpp
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/driver/android_usb_device_object.h b/host/windows/usb/legacy/driver/android_usb_device_object.h
deleted file mode 100755
index 698dc87..0000000
--- a/host/windows/usb/legacy/driver/android_usb_device_object.h
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_DEVICE_OBJECT_H__
-#define ANDROID_USB_DEVICE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbDeviceObject that
- encapsulates an extension for KMDF device (FDO) object.
-*/
-
-#include "android_usb_wdf_object.h"
-
-// Forward declaration for file object extension
-class AndroidUsbFileObject;
-
-/** AndroidUsbDeviceObject class encapsulates an extension for KMDF FDO device
- object. Instances of this class must be allocated from NonPagedPool.
-*/
-class AndroidUsbDeviceObject : public AndroidUsbWdfObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- */
- AndroidUsbDeviceObject();
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- ~AndroidUsbDeviceObject();
-
- public:
- /** \brief Creates and initializes FDO device object extension
-
- This method is called from driver's OnAddDevice method in response to
- AddDevice call from the PnP manager
- @param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
- structure.
- @return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
- it returns one of the error status values defined in ntstatus.h.
- */
- NTSTATUS CreateFDODevice(PWDFDEVICE_INIT device_init);
-
- /** \brief Resets target device
-
- When executing this method instance of this class may be deleted!
- This method must be called at PASSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code
- */
- NTSTATUS ResetDevice();
-
- private:
- /** \name Device event handlers and callbacks
- */
- ///@{
-
- /** \brief Handler for PnP prepare hardware event
-
- This method performs any operations that are needed to make a device
- accessible to the driver. The framework calls this callback after the PnP
- manager has assigned hardware resources to the device and after the device
- has entered its uninitialized D0 state. This callback is called before
- calling the driver's EvtDeviceD0Entry callback function.
- This method is called at PASSIVE IRQL.
- @param resources_raw[in] A handle to a framework resource-list object that
- identifies the raw hardware resources that the PnP manager has
- assigned to the device.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- NTSTATUS OnEvtDevicePrepareHardware(WDFCMRESLIST resources_raw,
- WDFCMRESLIST resources_translated);
-
- /** \brief Handler for PnP release hardware event
-
- This method performs operations that that are needed when a device is no
- longer accessible. Framework calls the callback function if the device is
- being removed, or if the PnP manager is attempting to redistribute hardware
- resources. The framework calls the EvtDeviceReleaseHardware callback
- function after the driver's device has been shut off, the PnP manager has
- reclaimed the hardware resources that it assigned to the device, and the
- device is no longer accessible. (The PCI configuration state is still
- accessible.) Typically, a EvtDeviceReleaseHardware callback function unmaps
- memory that the driver's EvtDevicePrepareHardware callback function mapped.
- Usually, all other hardware shutdown operations should take place in the
- driver's EvtDeviceD0Exit callback function.
- This method is called at PASSIVE IRQL.
- @param wdf_device[in] A handle to a framework device object.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- NTSTATUS OnEvtDeviceReleaseHardware(WDFCMRESLIST resources_translated);
-
- /** \brief Handler for create file event (request)
-
- This method performs operations that are needed when an application
- requests access to an item within this device path (including device
- itself). This method is called synchronously, in the context of the
- user thread that opens the item.
- This method is called at PASSIVE IRQL.
- @param request[in] A handle to a framework request object that represents
- a file creation request.
- @param wdf_fo[in] A handle to a framework file object that describes a
- file that is being created with this request.
- @return Successful status or an appropriate error code
- */
- void OnEvtDeviceFileCreate(WDFREQUEST request, WDFFILEOBJECT wdf_fo);
-
- /** \brief Entry point for PnP prepare hardware event
-
- This callback performs any operations that are needed to make a device
- accessible to the driver. The framework calls this callback after the PnP
- manager has assigned hardware resources to the device and after the device
- has entered its uninitialized D0 state. This callback is called before
- calling the driver's EvtDeviceD0Entry callback function.
- This callback is called at PASSIVE IRQL.
- @param wdf_dev[in] A handle to a framework device object.
- @param resources_raw[in] A handle to a framework resource-list object that
- identifies the raw hardware resources that the PnP manager has
- assigned to the device.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- static NTSTATUS EvtDevicePrepareHardwareEntry(WDFDEVICE wdf_dev,
- WDFCMRESLIST resources_raw,
- WDFCMRESLIST resources_translated);
-
- /** \brief Entry point for PnP release hardware event
-
- This callback performs operations that that are needed when a device is no
- longer accessible. Framework calls the callback function if the device is
- being removed, or if the PnP manager is attempting to redistribute hardware
- resources. The framework calls the EvtDeviceReleaseHardware callback
- function after the driver's device has been shut off, the PnP manager has
- reclaimed the hardware resources that it assigned to the device, and the
- device is no longer accessible. (The PCI configuration state is still
- accessible.) Typically, a EvtDeviceReleaseHardware callback function unmaps
- memory that the driver's EvtDevicePrepareHardware callback function mapped.
- Usually, all other hardware shutdown operations should take place in the
- driver's EvtDeviceD0Exit callback function.
- This callback is called at PASSIVE IRQL.
- @param wdf_dev[in] A handle to a framework device object.
- @param resources_translated[in] A handle to a framework resource-list
- object that identifies the translated hardware resources that the
- PnP manager has assigned to the device.
- @return Successful status or an appropriate error code
- */
- static NTSTATUS EvtDeviceReleaseHardwareEntry(WDFDEVICE wdf_dev,
- WDFCMRESLIST resources_translated);
-
- /** \brief Entry point for create file event (request)
-
- This callback performs operations that that are needed when an application
- requests access to a device. The framework calls a driver's
- EvtDeviceFileCreate callback function when a user application or another
- driver opens the device (or file on this device) to perform an I/O
- operation, such as reading or writing a file. This callback function is
- called synchronously, in the context of the user thread that opens the
- device.
- This callback is called at PASSIVE IRQL.
- @param wdf_dev[in] A handle to a framework device object.
- @param request[in] A handle to a framework request object that represents
- a file creation request.
- @param wdf_fo[in] A handle to a framework file object that describes a
- file that is being created with this request.
- @return Successful status or an appropriate error code
- */
- static void EvtDeviceFileCreateEntry(WDFDEVICE wdf_dev,
- WDFREQUEST request,
- WDFFILEOBJECT wdf_fo);
-
- ///@}
-
- private:
- /** \name I/O request event handlers and callbacks
- */
- ///@{
-
- /** \brief Read event handler
-
- This method is called when a read request comes to a file object opened
- on this device.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- */
- void OnEvtIoRead(WDFREQUEST request, size_t length);
-
- /** \brief Write event handler
-
- This method is called when a write request comes to a file object opened
- on this device.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- */
- void OnEvtIoWrite(WDFREQUEST request, size_t length);
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to a file object
- opened on this device.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- */
- void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- /** \brief Entry point for read event
-
- This callback is called when a read request comes to a file object opened
- on this device.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param queue[in] A handle to the framework queue object that is associated
- with the I/O request.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- */
- static void EvtIoReadEntry(WDFQUEUE queue,
- WDFREQUEST request,
- size_t length);
-
- /** \brief Entry point for write event
-
- This callback is called when a write request comes to a file object opened
- on this device.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param queue[in] A handle to the framework queue object that is associated
- with the I/O request.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- */
- static void EvtIoWriteEntry(WDFQUEUE queue,
- WDFREQUEST request,
- size_t length);
-
- /** \brief Entry point for device IOCTL event
-
- This callback is called when a device control request comes to a file
- object opened on this device.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param queue[in] A handle to the framework queue object that is associated
- with the I/O request.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- */
- static void EvtIoDeviceControlEntry(WDFQUEUE queue,
- WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- ///@}
-
- public:
- /** \name Device level I/O request handlers
- */
- ///@{
-
- /** \brief Gets USB device descriptor
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetUsbDeviceDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
-
- /** \brief Gets USB configuration descriptor for the selected configuration.
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetUsbConfigDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
-
- /** \brief Gets USB configuration descriptor for the selected interface.
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetUsbInterfaceDescriptorCtl(WDFREQUEST request, size_t output_buf_len);
-
- /** \brief Gets information about an endpoint.
-
- This method can be called at IRQL <= DISPATCH_LEVEL
- @param request[in] A handle to a framework request object for this IOCTL.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetEndpointInformationCtl(WDFREQUEST request,
- size_t input_buf_len,
- size_t output_buf_len);
-
- /** \brief Gets device serial number.
-
- Serial number is returned in form of zero-terminated string that in the
- output buffer. This method must be called at low IRQL.
- @param request[in] A handle to a framework request object for this IOCTL.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- void OnGetSerialNumberCtl(WDFREQUEST request, size_t output_buf_len);
-
- ///@}
-
- private:
- /** \name Internal methods
- */
- ///@{
-
- /** \brief Creates default request queue for this device.
-
- In KMDF all I/O requests are coming through the queue object. So, in order
- to enable our device to receive I/O requests we must create a queue for it.
- This method is called at PASSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- NTSTATUS CreateDefaultQueue();
-
- /** \brief Configures our device.
-
- This method is called from the prepare hardware handler after underlying
- FDO device has been created.
- This method is called at PASSSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- NTSTATUS ConfigureDevice();
-
- /** \brief Selects interfaces on our device.
-
- This method is called from the prepare hardware handler after underlying
- FDO device has been created and configured.
- This method is called at PASSSIVE IRQL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- NTSTATUS SelectInterfaces();
-
- /** \brief Gets pipe index from a file name
-
- This method is called from OnEvtDeviceFileCreate to determine index of
- the pipe this file is addressing.
- This method is called at PASSIVE IRQL.
- @param file_path[in] Path to the file that being opened.
- @return Pipe index or INVALID_UCHAR if index cannot be calculated.
- */
- UCHAR GetPipeIndexFromFileName(PUNICODE_STRING file_path);
-
- /** \brief Creates file object extension for a pipe
-
- This method is called from OnEvtDeviceFileCreate to create an appropriate
- file object extension for a particular pipe type.
- This method is called at PASSIVE IRQL.
- @param wdf_fo[in] KMDF file to extend.
- @param wdf_pipe_obj[in] KMDF pipe for this extension
- @param pipe_info[in] Pipe information
- @param wdf_file_ext[out] Upon successfull completion will receive instance
- of the extension.
- @return STATUS_SUCCESS or an appropriate error code
- */
- NTSTATUS CreatePipeFileObjectExt(WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj,
- const WDF_USB_PIPE_INFORMATION* pipe_info,
- AndroidUsbFileObject** wdf_file_ext);
-
- ///@}
-
- private:
- /** \name Debugging support
- */
- ///@{
-
-#if DBG
- /// Prints USB_DEVICE_DESCRIPTOR to debug output
- void PrintUsbDeviceDescriptor(const USB_DEVICE_DESCRIPTOR* desc);
-
- /// Prints WDF_USB_DEVICE_INFORMATION to debug output
- void PrintUsbTargedDeviceInformation(const WDF_USB_DEVICE_INFORMATION* info);
-
- /// Prints USB_CONFIGURATION_DESCRIPTOR to debug output
- void PrintConfigDescriptor(const USB_CONFIGURATION_DESCRIPTOR* desc,
- ULONG size);
-
- /// Prints WDF_USB_DEVICE_SELECT_CONFIG_PARAMS to debug output
- void PrintSelectedConfig(const WDF_USB_DEVICE_SELECT_CONFIG_PARAMS* config);
-
- /// Prints USB_INTERFACE_DESCRIPTOR to debug output
- void PrintInterfaceDescriptor(const USB_INTERFACE_DESCRIPTOR* desc);
-
- /// Prints WDF_USB_PIPE_INFORMATION to debug output
- void PrintPipeInformation(const WDF_USB_PIPE_INFORMATION* info,
- UCHAR pipe_index);
-
-#endif // DBG
-
- ///@}
-
- public:
- /// Gets WDF device handle for this device
- __forceinline WDFDEVICE wdf_device() const {
- return reinterpret_cast<WDFDEVICE>(wdf_object());
- }
-
- /// Gets target USB device descriptor
- __forceinline const USB_DEVICE_DESCRIPTOR* usb_device_descriptor() const {
- return &usb_device_descriptor_;
- }
-
- /// Gets target USB device information
- __forceinline const WDF_USB_DEVICE_INFORMATION* usb_device_info() const {
- return &usb_device_info_;
- }
-
- /// Gets selected interface descriptor
- __forceinline const USB_INTERFACE_DESCRIPTOR* interface_descriptor() const {
- return &interface_descriptor_;
- }
-
- /// Gets target (PDO) device handle
- __forceinline WDFUSBDEVICE wdf_target_device() const {
- return wdf_target_device_;
- }
-
- /// Checks if target device has been created
- __forceinline bool IsTaretDeviceCreated() const {
- return (NULL != wdf_target_device());
- }
-
- /// Gets USB configuration descriptor
- __forceinline const USB_CONFIGURATION_DESCRIPTOR* configuration_descriptor() const {
- return configuration_descriptor_;
- }
-
- /// Checks if device has been configured
- __forceinline bool IsDeviceConfigured() const {
- return (NULL != configuration_descriptor());
- }
-
- /// Gets number of interfaces for this device
- __forceinline UCHAR GetInterfaceCount() const {
- ASSERT(IsDeviceConfigured());
- return IsDeviceConfigured() ? configuration_descriptor()->bNumInterfaces : 0;
- }
-
- /// Checks if this is "single interface" device
- __forceinline bool IsSingleInterfaceDevice() const {
- return (1 == GetInterfaceCount());
- }
-
- /// Gets USB interface selected on this device
- __forceinline WDFUSBINTERFACE wdf_usb_interface() const {
- return wdf_usb_interface_;
- }
-
- /// Checks if an interface has been selected on this device
- __forceinline bool IsInterfaceSelected() const {
- return (NULL != wdf_usb_interface());
- }
-
- /// Gets number of pipes configured on this device
- __forceinline UCHAR configured_pipes_num() const {
- return configured_pipes_num_;
- }
-
- /// Gets index of the bulk read pipe
- __forceinline UCHAR bulk_read_pipe_index() const {
- return bulk_read_pipe_index_;
- }
-
- /// Gets index of the bulk write pipe
- __forceinline UCHAR bulk_write_pipe_index() const {
- return bulk_write_pipe_index_;
- }
-
- /// Checks if this is a high speed device
- __forceinline bool IsHighSpeed() const {
- return (0 != (usb_device_info()->Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED));
- }
-
- /// Checks if bulk read pipe index is known
- __forceinline bool IsBulkReadPipeKnown() const {
- return (INVALID_UCHAR != bulk_read_pipe_index());
- }
-
- /// Checks if bulk write pipe index is known
- __forceinline bool IsBulkWritePipeKnown() const {
- return (INVALID_UCHAR != bulk_write_pipe_index());
- }
-
- /// Gets device serial number string. Note that string may be
- /// not zero-terminated. Use serial_number_len() to get actual
- /// length of this string.
- __forceinline const WCHAR* serial_number() const {
- ASSERT(NULL != serial_number_handle_);
- return (NULL != serial_number_handle_) ?
- reinterpret_cast<const WCHAR*>
- (WdfMemoryGetBuffer(serial_number_handle_, NULL)) :
- NULL;
- }
-
- /// Gets length (in bytes) of device serial number string
- __forceinline USHORT serial_number_char_len() const {
- return serial_number_char_len_;
- }
-
- /// Gets length (in bytes) of device serial number string
- __forceinline USHORT serial_number_byte_len() const {
- return serial_number_char_len() * sizeof(WCHAR);
- }
-
- protected:
- /// Target USB device descriptor
- USB_DEVICE_DESCRIPTOR usb_device_descriptor_;
-
- /// Target USB device information
- WDF_USB_DEVICE_INFORMATION usb_device_info_;
-
- /// Selected interface descriptor
- USB_INTERFACE_DESCRIPTOR interface_descriptor_;
-
- /// USB configuration descriptor
- PUSB_CONFIGURATION_DESCRIPTOR configuration_descriptor_;
-
- /// Target (PDO?) device handle
- WDFUSBDEVICE wdf_target_device_;
-
- /// USB interface selected on this device
- WDFUSBINTERFACE wdf_usb_interface_;
-
- /// Device serial number
- WDFMEMORY serial_number_handle_;
-
- /// Device serial number string length
- USHORT serial_number_char_len_;
-
- /// Number of pipes configured on this device
- UCHAR configured_pipes_num_;
-
- /// Index of the bulk read pipe
- UCHAR bulk_read_pipe_index_;
-
- /// Index of the bulk write pipe
- UCHAR bulk_write_pipe_index_;
-};
-
-/** \brief Gets device KMDF object extension for the given KMDF object
-
- @param wdf_dev[in] KMDF handle describing device object
- @return Instance of AndroidUsbDeviceObject associated with KMDF object or
- NULL if association is not found.
-*/
-__forceinline AndroidUsbDeviceObject* GetAndroidUsbDeviceObjectFromHandle(
- WDFDEVICE wdf_dev) {
- AndroidUsbWdfObject* wdf_object_ext =
- GetAndroidUsbWdfObjectFromHandle(wdf_dev);
- ASSERT((NULL != wdf_object_ext) &&
- wdf_object_ext->Is(AndroidUsbWdfObjectTypeDevice));
- if ((NULL != wdf_object_ext) &&
- wdf_object_ext->Is(AndroidUsbWdfObjectTypeDevice)) {
- return reinterpret_cast<AndroidUsbDeviceObject*>(wdf_object_ext);
- }
- return NULL;
-}
-
-#endif // ANDROID_USB_DEVICE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_driver_defines.h b/host/windows/usb/legacy/driver/android_usb_driver_defines.h
deleted file mode 100755
index da976e5..0000000
--- a/host/windows/usb/legacy/driver/android_usb_driver_defines.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_DRIVER_DEFINES_H__
-#define ANDROID_USB_DRIVER_DEFINES_H__
-/** \file
- This file consists of constants, types and macros used (and useful) in driver
- development.
-*/
-
-/** \name IRQL assertions
- These assertions help to verify that code is running at expected IRQL
-*/
-///@{
-
-/// Asserts that current IRQL is less than provided level
-#define ASSERT_IRQL_LESS(irql_level) ASSERT(KeGetCurrentIrql() < irql_level)
-/// Asserts that current IRQL is less or equal than provided level
-#define ASSERT_IRQL_LESS_OR_EQUAL(irql_level) ASSERT(KeGetCurrentIrql() <= irql_level)
-/// Asserts that current IRQL is the same as provided level
-#define ASSERT_IRQL_IS(irql_level) ASSERT(irql_level == KeGetCurrentIrql())
-/// Asserts that current IRQL is less than DISPATCH_LEVEL
-#define ASSERT_IRQL_LOW() ASSERT_IRQL_LESS(DISPATCH_LEVEL)
-/// Asserts that current IRQL is above APC_LEVEL
-#define ASSERT_IRQL_HIGH() ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL)
-/// Asserts that current IRQL is at PASSIVE_LEVEL
-#define ASSERT_IRQL_PASSIVE() ASSERT_IRQL_IS(PASSIVE_LEVEL)
-/// Asserts that current IRQL is at APC_LEVEL
-#define ASSERT_IRQL_APC() ASSERT_IRQL_IS(APC_LEVEL)
-/// Asserts that current IRQL is at DISPATCH_LEVEL
-#define ASSERT_IRQL_DISPATCH() ASSERT_IRQL_IS(DISPATCH_LEVEL)
-/// Asserts that current IRQL is at APC or DISPATCH_LEVEL
-#define ASSERT_IRQL_APC_OR_DISPATCH() \
- ASSERT((KeGetCurrentIrql() == APC_LEVEL) || (KeGetCurrentIrql() == DISPATCH_LEVEL))
-/// Asserts that current IRQL is less or equal DISPATCH_LEVEL
-#define ASSERT_IRQL_LOW_OR_DISPATCH() \
- ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL)
-
-///@}
-
-#if DBG
-/** \brief Overrides DbgPrint to make sure that nothing gets printed
- to debug output in release build.
-*/
-ULONG __cdecl GoogleDbgPrint(char* format, ...);
-#else
-#define GoogleDbgPrint(Arg) NOTHING
-#endif
-
-/// Invalid UCHAR value
-#define INVALID_UCHAR (static_cast<UCHAR>(0xFF))
-
-/// Invalid ULONG value
-#define INVALID_ULONG (static_cast<ULONG>(-1))
-
-/** Enum AndroidUsbWdfObjectType enumerates types of KMDF objects that
- we extend in our driver.
-*/
-enum AndroidUsbWdfObjectType {
- // We start enum with 1 insetead of 0 to protect orselves from a dangling
- // or uninitialized context structures because KMDF will zero our extension
- // when it gets created.
-
- /// Device object context
- AndroidUsbWdfObjectTypeDevice = 1,
-
- /// File object context
- AndroidUsbWdfObjectTypeFile,
-
- /// Request object context
- AndroidUsbWdfObjectTypeRequest,
-
- /// Workitem object context
- AndroidUsbWdfObjectTypeWorkitem,
-
- /// Illegal (maximum) context id
- AndroidUsbWdfObjectTypeMax
-};
-
-/** Structure AndroidUsbWdfObjectContext represents our context that extends
- every KMDF object (device, file, pipe, etc).
-*/
-typedef struct TagAndroidUsbWdfObjectContext {
- /// KMDF object type that is extended with this context
- AndroidUsbWdfObjectType object_type;
-
- /// Instance of the class that extends KMDF object with this context
- class AndroidUsbWdfObject* wdf_object_ext;
-} AndroidUsbWdfObjectContext;
-
-// KMDF woodoo to register our extension and implement accessor method
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfObjectContext,
- GetAndroidUsbWdfObjectContext)
-
-/** Structure AndroidUsbWdfRequestContext represents our context that is
- associated with every request recevied by the driver.
-*/
-typedef struct TagAndroidUsbWdfRequestContext {
- /// KMDF object type that is extended with this context
- /// (must be AndroidUsbWdfObjectTypeRequest)
- AndroidUsbWdfObjectType object_type;
-
- /// System time request has been first scheduled
- // (time of the first WdfRequestSend is called for it)
- LARGE_INTEGER sent_at;
-
- /// KMDF descriptor for the memory allocated for URB
- WDFMEMORY urb_mem;
-
- /// MDL describing the transfer buffer
- PMDL transfer_mdl;
-
- /// Private MDL that we build in order to perform the transfer
- PMDL mdl;
-
- // Virtual address for the current segment of transfer.
- void* virtual_address;
-
- /// Number of bytes remaining to transfer
- ULONG length;
-
- /// Number of bytes requested to transfer
- ULONG transfer_size;
-
- /// Accummulated number of bytes transferred
- ULONG num_xfer;
-
- /// Initial timeout (in millisec) set for this request
- ULONG initial_time_out;
-
- // Read / Write selector
- bool is_read;
-
- // IOCTL selector
- bool is_ioctl;
-} AndroidUsbWdfRequestContext;
-
-// KMDF woodoo to register our extension and implement accessor method
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWdfRequestContext,
- GetAndroidUsbWdfRequestContext)
-
-/** Structure AndroidUsbWorkitemContext represents our context that is
- associated with workitems created by our driver.
-*/
-typedef struct TagAndroidUsbWorkitemContext {
- /// KMDF object type that is extended with this context
- /// (must be AndroidUsbWdfObjectTypeWorkitem)
- AndroidUsbWdfObjectType object_type;
-
- /// Pipe file object extension that enqueued this work item
- class AndroidUsbPipeFileObject* pipe_file_ext;
-} AndroidUsbWorkitemContext;
-
-// KMDF woodoo to register our extension and implement accessor method
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(AndroidUsbWorkitemContext,
- GetAndroidUsbWorkitemContext)
-
-#endif // ANDROID_USB_DRIVER_DEFINES_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_driver_object.cpp b/host/windows/usb/legacy/driver/android_usb_driver_object.cpp
deleted file mode 100755
index 770a13a..0000000
--- a/host/windows/usb/legacy/driver/android_usb_driver_object.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbDriverObject that
- encapsulates our driver object
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_device_object.h"
-#include "android_usb_driver_object.h"
-
-#pragma data_seg()
-
-/** Globally accessible instance of the AndroidUsbDriverObject.
- NT OS design allows us using of a global pointer to our driver object
- instance since it can't be created or destroyed concurently and its value
- is not going to change between creation and destruction.
-*/
-AndroidUsbDriverObject* global_driver_object = NULL;
-
-#pragma code_seg("INIT")
-
-extern "C" {
-
-/// Main entry point to the driver
-NTSTATUS DriverEntry(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path) {
- // Just pass it down inside the class
- return AndroidUsbDriverObject::DriverEntry(drv_object, reg_path);
-}
-
-} // extern "C"
-
-NTSTATUS AndroidUsbDriverObject::DriverEntry(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != drv_object);
- ASSERT((NULL != reg_path) &&
- (NULL != reg_path->Buffer) &&
- (0 != reg_path->Length));
-
- // Instantiate driver object
- global_driver_object = new(NonPagedPool, GANDR_POOL_TAG_DRIVER_OBJECT)
- AndroidUsbDriverObject(drv_object, reg_path);
- ASSERT(NULL != global_driver_object);
- if (NULL == global_driver_object)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- // Initialize driver object
- NTSTATUS status = global_driver_object->OnDriverEntry(drv_object, reg_path);
-
- if (!NT_SUCCESS(status)) {
- // Something went wrong. Delete our driver object and get out of here.
- delete global_driver_object;
- }
-
- return status;
-}
-
-AndroidUsbDriverObject::AndroidUsbDriverObject(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path)
- : driver_object_(drv_object),
- wdf_driver_(NULL) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != driver_object());
-}
-
-NTSTATUS AndroidUsbDriverObject::OnDriverEntry(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(driver_object() == drv_object);
-
- // Initiialize driver config, specifying our unload callback and default
- // pool tag for memory allocations that KMDF does on our behalf.
- WDF_DRIVER_CONFIG config;
- WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAddEntry);
- config.EvtDriverUnload = EvtDriverUnloadEntry;
- config.DriverPoolTag = GANDR_POOL_TAG_DEFAULT;
-
- // Create a framework driver object to represent our driver.
- NTSTATUS status = WdfDriverCreate(drv_object,
- reg_path,
- WDF_NO_OBJECT_ATTRIBUTES,
- &config,
- &wdf_driver_);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status))
- return status;
-
- GoogleDbgPrint("\n>>>>>>>>>> Android USB driver has started >>>>>>>>>>");
-
- return STATUS_SUCCESS;
-}
-
-#pragma code_seg("PAGE")
-
-AndroidUsbDriverObject::~AndroidUsbDriverObject() {
- ASSERT_IRQL_PASSIVE();
-}
-
-NTSTATUS AndroidUsbDriverObject::OnAddDevice(PWDFDEVICE_INIT device_init) {
- ASSERT_IRQL_PASSIVE();
- GoogleDbgPrint("\n++++++++++ AndroidUsbDriverObject::OnAddDevice ++++++++++");
- // Instantiate our device object extension for this device
- AndroidUsbDeviceObject* wdf_device_ext =
- new(NonPagedPool, GANDR_POOL_TAG_KMDF_DEVICE) AndroidUsbDeviceObject();
- ASSERT(NULL != wdf_device_ext);
- if (NULL == wdf_device_ext)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- // Create and initialize FDO device
- NTSTATUS status = wdf_device_ext->CreateFDODevice(device_init);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status))
- delete wdf_device_ext;
-
- return status;
-}
-
-void AndroidUsbDriverObject::OnDriverUnload() {
- ASSERT_IRQL_PASSIVE();
- GoogleDbgPrint("\n<<<<<<<<<< Android USB driver is unloaded <<<<<<<<<<");
-}
-
-NTSTATUS AndroidUsbDriverObject::EvtDeviceAddEntry(
- WDFDRIVER wdf_drv,
- PWDFDEVICE_INIT device_init) {
- ASSERT_IRQL_PASSIVE();
- ASSERT((NULL != global_driver_object) && (global_driver_object->wdf_driver() == wdf_drv));
-
- // Pass it down to our driver object
- if ((NULL == global_driver_object) ||
- (global_driver_object->wdf_driver() != wdf_drv)) {
- return STATUS_INTERNAL_ERROR;
- }
-
- return global_driver_object->OnAddDevice(device_init);
-}
-
-VOID AndroidUsbDriverObject::EvtDriverUnloadEntry(WDFDRIVER wdf_drv) {
- ASSERT_IRQL_PASSIVE();
- ASSERT((NULL != global_driver_object) &&
- (global_driver_object->wdf_driver() == wdf_drv));
-
- // Pass it down to our driver object
- if ((NULL != global_driver_object) &&
- (global_driver_object->wdf_driver() == wdf_drv)) {
- global_driver_object->OnDriverUnload();
- // Now we can (and have to) delete our driver object
- delete global_driver_object;
- }
-}
-
-#if DBG
-
-#pragma code_seg()
-
-ULONG __cdecl GoogleDbgPrint(char* format, ...) {
- va_list arg_list;
- va_start(arg_list, format);
- ULONG ret =
- vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, arg_list);
- va_end(arg_list);
-
- return ret;
-}
-
-#endif // DBG
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_driver_object.h b/host/windows/usb/legacy/driver/android_usb_driver_object.h
deleted file mode 100755
index 568b977..0000000
--- a/host/windows/usb/legacy/driver/android_usb_driver_object.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_DRIVER_OBJECT_H__
-#define ANDROID_USB_DRIVER_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbDriverObject that
- encapsulates our driver object.
-*/
-
-/// Globally accessible pointer to the driver object
-extern class AndroidUsbDriverObject* global_driver_object;
-
-/** AndroidUsbDriverObject class encapsulates driver object and provides
- overall initialization / cleanup as well as management of globally used
- resources. We use KMDF framework for this driver because it takes care of
- most of the USB related "things" (like PnP, power management and other
- stuff) so we can concentrate more on real functionality. This driver is
- based on KMDF's usbsamp driver sample available at DDK's src\kmdf\usbsamp
- directory. Instance of this class (always one) must be allocated from
- NonPagedPool.
-*/
-class AndroidUsbDriverObject {
-
- public:
- /** \brief Driver initialization entry point.
-
- This method is a "gate" to our driver class from main DriverEntry routine.
- Since this method is called from within DriverEntry only it is placed in
- "INIT" code segment.
- This method is called at IRQL PASSIVE_LEVEL.
- @param drv_object[in] Driver object passed to DriverEntry routine
- @param reg_path[in] Path to the driver's Registry passed to DriverEntry
- routine
- @returns STATUS_SUCCESS on success or an appropriate error code.
- */
- static NTSTATUS DriverEntry(PDRIVER_OBJECT drv_object,
- PUNICODE_STRING reg_path);
-
- private:
- /** \brief Constructs driver object.
-
- Constructor for driver class must be as light as possible. All
- initialization that may fail must be deferred to OnDriverEntry method.
- Since this method is called from within DriverEntry only it is placed in
- "INIT" code segment.
- This method is called at IRQL PASSIVE_LEVEL.
- @param drv_object[in] Driver object passed to DriverEntry routine
- @param reg_path[in] Path to the driver's Registry passed to DriverEntry
- routine
- */
- AndroidUsbDriverObject(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path);
-
- /** \brief Destructs driver object.
-
- Destructor for driver class must be as light as possible. All
- uninitialization must be done in OnDriverUnload method.
- This method must be called at PASSIVE IRQL.
- */
- ~AndroidUsbDriverObject();
-
- /** \brief Initializes instance of the driver object.
-
- This method is called immediatelly after driver object has been
- instantiated to perform actual initialization of the driver. Since this
- method is called from within DriverEntry only it is placed in
- "INIT" code segment.
- This method is called at IRQL PASSIVE_LEVEL.
- @param drv_object[in] Driver object passed to DriverEntry routine
- @param reg_path[in] Path to the driver's Registry passed to DriverEntry
- routine
- @returns STATUS_SUCCESS on success or an appropriate error code.
- */
- NTSTATUS OnDriverEntry(PDRIVER_OBJECT drv_object, PUNICODE_STRING reg_path);
-
- /** \brief Actual handler for KMDF's AddDevice event
-
- This method is called by the framework in response to AddDevice call from
- the PnP manager. We create and initialize a device object to represent a
- new instance of the device.
- This method is called at IRQL PASSIVE_LEVEL.
- @param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
- structure.
- @return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
- it returns one of the error status values defined in ntstatus.h.
- */
- NTSTATUS OnAddDevice(PWDFDEVICE_INIT device_init);
-
- /** \brief Actual driver unload event handler.
-
- This method is called when driver is being unloaded.
- This method is called at IRQL PASSIVE_LEVEL.
- */
- void OnDriverUnload();
-
- /** \brief KMDF's DeviceAdd event entry point
-
- This callback is called by the framework in response to AddDevice call from
- the PnP manager. We create and initialize a device object to represent a
- new instance of the device. All the software resources should be allocated
- in this callback.
- This method is called at IRQL PASSIVE_LEVEL.
- @param wdf_drv[in] WDF driver handle.
- @param device_init[in] A pointer to a framework-allocated WDFDEVICE_INIT
- structure.
- @return If the routine succeeds, it returns STATUS_SUCCESS. Otherwise,
- it returns one of the error status values defined in ntstatus.h.
- */
- static NTSTATUS EvtDeviceAddEntry(WDFDRIVER wdf_drv,
- PWDFDEVICE_INIT device_init);
-
- /** \brief Driver unload event entry point.
-
- Framework calls this callback when driver is being unloaded.
- This method is called at IRQL PASSIVE_LEVEL.
- */
- static VOID EvtDriverUnloadEntry(WDFDRIVER wdf_drv);
-
- public:
-
- /// Gets this driver's DRIVER_OBJECT
- __forceinline PDRIVER_OBJECT driver_object() const {
- return driver_object_;
- }
-
- /// Gets KMDF driver handle
- __forceinline WDFDRIVER wdf_driver() const {
- return wdf_driver_;
- }
-
- private:
- /// This driver's driver object
- PDRIVER_OBJECT driver_object_;
-
- /// KMDF driver handle
- WDFDRIVER wdf_driver_;
-};
-
-#endif // ANDROID_USB_DRIVER_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_file_object.cpp
deleted file mode 100755
index 196faec..0000000
--- a/host/windows/usb/legacy/driver/android_usb_file_object.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbFileObject that
- encapsulates a common extension for all KMDF file object types.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbFileObject::AndroidUsbFileObject(AndroidUsbFileObjectType fo_type,
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo)
- : AndroidUsbWdfObject(AndroidUsbWdfObjectTypeFile),
- file_type_(fo_type),
- device_object_(dev_obj) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != dev_obj);
- ASSERT(fo_type < AndroidUsbFileObjectTypeMax);
- ASSERT(NULL != wdf_fo);
- set_wdf_object(wdf_fo);
-}
-
-#pragma code_seg()
-
-AndroidUsbFileObject::~AndroidUsbFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma code_seg("PAGE")
-
-NTSTATUS AndroidUsbFileObject::Initialize() {
- ASSERT_IRQL_LOW();
- ASSERT(NULL != wdf_file());
- if (NULL == wdf_file())
- return STATUS_INTERNAL_ERROR;
-
- // Register context for this file object
- return InitializeContext();
-}
-
-#pragma code_seg()
-
-void AndroidUsbFileObject::OnEvtIoRead(WDFREQUEST request,
- size_t length) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- ASSERT(WdfRequestGetFileObject(request) == wdf_file());
- // Complete zero reads with success
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
-}
-
-void AndroidUsbFileObject::OnEvtIoWrite(WDFREQUEST request,
- size_t length) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- ASSERT(WdfRequestGetFileObject(request) == wdf_file());
- // Complete zero writes with success
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
-}
-
-void AndroidUsbFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- ASSERT(WdfRequestGetFileObject(request) == wdf_file());
-
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_REQUEST);
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_file_object.h b/host/windows/usb/legacy/driver/android_usb_file_object.h
deleted file mode 100755
index f845478..0000000
--- a/host/windows/usb/legacy/driver/android_usb_file_object.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_FILE_OBJECT_H__
-#define ANDROID_USB_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbFileObject that
- encapsulates a common extension for all KMDF file object types.
-*/
-
-#include "android_usb_wdf_object.h"
-#include "android_usb_device_object.h"
-
-/** Enumerator AndroidUsbFileObjectType defines possible types for our file
- object extension.
-*/
-enum AndroidUsbFileObjectType {
- /// File extends device FO
- AndroidUsbFileObjectTypeDevice,
-
- // File extends a pipe FO
- AndroidUsbFileObjectTypePipe,
-
- AndroidUsbFileObjectTypeMax,
-};
-
-/** AndroidUsbFileObject class encapsulates a common extension for all KMDF
- file object types. Instances of this class must be allocated from
- NonPagedPool.
-*/
-class AndroidUsbFileObject : public AndroidUsbWdfObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param fo_type[in] Type of the file object that this object extends
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object for this extension
- */
- AndroidUsbFileObject(AndroidUsbFileObjectType fo_type,
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbFileObject();
-
- /** \brief Initializes the object
-
- This method verifies that instance has been created and calls base class's
- InitializeContext method to register itself with the wrapped FO. All
- derived classes must call this method when initializing.
- This method must be called at low IRQL.
- @return STATUS_SUCCESS on success or an appropriate error code
- */
- virtual NTSTATUS Initialize();
-
- /** \brief Read event handler
-
- This method is called when a read request comes to the file object this
- class extends.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoRead(WDFREQUEST request, size_t length);
-
- /** \brief Write event handler
-
- This method is called when a write request comes to the file object this
- class extends.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoWrite(WDFREQUEST request, size_t length);
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to the file
- object this class extends.
- This callback can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- public:
- /// Gets KMDF file handle for this extension
- __forceinline WDFFILEOBJECT wdf_file() const {
- return reinterpret_cast<WDFFILEOBJECT>(wdf_object());
- }
-
- /// Gets device object that owns this file
- __forceinline AndroidUsbDeviceObject* device_object() const {
- return device_object_;
- }
-
- /// Gets type of the file object that this extension wraps
- __forceinline AndroidUsbFileObjectType file_type() const {
- return file_type_;
- }
-
- /// Gets WDF device handle for device that owns this file
- __forceinline WDFDEVICE wdf_device() const {
- ASSERT(NULL != device_object());
- return (NULL != device_object()) ? device_object()->wdf_device() :
- NULL;
- }
-
- /// Gets target (PDO) device handle for the device that owns this file
- __forceinline WDFUSBDEVICE wdf_target_device() const {
- ASSERT(NULL != device_object());
- return (NULL != device_object()) ? device_object()->wdf_target_device() :
- NULL;
- }
-
- protected:
- /// Device object that owns this file
- AndroidUsbDeviceObject* device_object_;
-
- /// Type of the file object that this extension wraps
- AndroidUsbFileObjectType file_type_;
-};
-
-/** \brief Gets file KMDF object extension for the given KMDF file object
-
- This method can be called at any IRQL
- @param wdf_fo[in] KMDF file handle describing file object
- @return Instance of AndroidUsbFileObject associated with this object or NULL
- if association is not found.
-*/
-__forceinline AndroidUsbFileObject* GetAndroidUsbFileObjectFromHandle(
- WDFFILEOBJECT wdf_fo) {
- AndroidUsbWdfObject* wdf_object_ext =
- GetAndroidUsbWdfObjectFromHandle(wdf_fo);
- ASSERT(NULL != wdf_object_ext);
- if (NULL != wdf_object_ext) {
- ASSERT(wdf_object_ext->Is(AndroidUsbWdfObjectTypeFile));
- if (wdf_object_ext->Is(AndroidUsbWdfObjectTypeFile))
- return reinterpret_cast<AndroidUsbFileObject*>(wdf_object_ext);
- }
- return NULL;
-}
-
-/** \brief Gets file KMDF file object extension for the given request
-
- This method can be called at any IRQL
- @param request[in] KMDF request object
- @return Instance of AndroidUsbFileObject associated with this request or NULL
- if association is not found.
-*/
-__forceinline AndroidUsbFileObject* GetAndroidUsbFileObjectForRequest(
- WDFREQUEST request) {
- return GetAndroidUsbFileObjectFromHandle(WdfRequestGetFileObject(request));
-}
-
-#endif // ANDROID_USB_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_inl.h b/host/windows/usb/legacy/driver/android_usb_inl.h
deleted file mode 100755
index d08ed18..0000000
--- a/host/windows/usb/legacy/driver/android_usb_inl.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_INL_H__
-#define ANDROID_USB_INL_H__
-/** \file
- This file consists of inline routines for the driver.
-*/
-
-/// Gets control code out of the entire IOCTL code packet
-__forceinline ULONG GetCtlCode(ULONG ioctl_code) {
- return (ioctl_code >> 2) & 0x0FFF;
-}
-
-/** \brief
- Converts string length from number of wide characters into number of bytes.
-*/
-__forceinline USHORT ByteLen(USHORT wchar_len) {
- return static_cast<USHORT>(wchar_len * sizeof(WCHAR));
-}
-
-/** \brief Gets byte length of a zero-terminated string not including
- zero terminator. Must be called at low IRQL.
-*/
-__forceinline USHORT ByteLen(const WCHAR* str) {
- ASSERT_IRQL_LOW();
- return (NULL != str) ? ByteLen(static_cast<USHORT>(wcslen(str))) : 0;
-}
-
-/** \brief
- Converts string length from number of bytes into number of wide characters.
- Can be called at any IRQL.
-*/
-__forceinline USHORT WcharLen(USHORT byte_len) {
- return byte_len / sizeof(WCHAR);
-}
-
-/** \brief Retrieves pointer out of the WDFMEMORY handle
-*/
-__forceinline void* GetAddress(WDFMEMORY wdf_mem) {
- ASSERT(NULL != wdf_mem);
- return (NULL != wdf_mem) ? WdfMemoryGetBuffer(wdf_mem, NULL) : NULL;
-}
-
-/** \brief Retrieves output memory address for WDFREQUEST
-
- @param request[in] A handle to KMDF request object
- @param status[out] Receives status of the call. Can be NULL.
-*/
-__forceinline void* OutAddress(WDFREQUEST request, NTSTATUS* status) {
- ASSERT(NULL != request);
- WDFMEMORY wdf_mem = NULL;
- NTSTATUS stat = WdfRequestRetrieveOutputMemory(request, &wdf_mem);
- ASSERT((NULL != wdf_mem) || (!NT_SUCCESS(stat)));
- if (NULL != status)
- *status = stat;
- return NT_SUCCESS(stat) ? GetAddress(wdf_mem) : NULL;
-}
-
-/** \brief Retrieves input memory address for WDFREQUEST
-
- @param request[in] A handle to KMDF request object
- @param status[out] Receives status of the call. Can be NULL.
-*/
-__forceinline void* InAddress(WDFREQUEST request, NTSTATUS* status) {
- ASSERT(NULL != request);
- WDFMEMORY wdf_mem = NULL;
- NTSTATUS stat = WdfRequestRetrieveInputMemory(request, &wdf_mem);
- ASSERT((NULL != wdf_mem) || (!NT_SUCCESS(stat)));
- if (NULL != status)
- *status = stat;
- return NT_SUCCESS(stat) ? GetAddress(wdf_mem) : NULL;
-}
-
-#endif // ANDROID_USB_INL_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.cpp
deleted file mode 100755
index 32c88ca..0000000
--- a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbInterruptPipeFileObject
- that encapsulates extension to an interrupt pipe file objects.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_interrupt_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbInterruptPipeFileObject::AndroidUsbInterruptPipeFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj)
- : AndroidUsbPipeFileObject(dev_obj, wdf_fo, wdf_pipe_obj) {
- ASSERT_IRQL_PASSIVE();
-
-#if DBG
- WDF_USB_PIPE_INFORMATION pipe_info;
- WDF_USB_PIPE_INFORMATION_INIT(&pipe_info);
- WdfUsbTargetPipeGetInformation(wdf_pipe_obj, &pipe_info);
- ASSERT(WdfUsbPipeTypeInterrupt == pipe_info.PipeType);
-#endif // DBG
-
-}
-
-#pragma code_seg()
-
-AndroidUsbInterruptPipeFileObject::~AndroidUsbInterruptPipeFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.h b/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.h
deleted file mode 100755
index 7b23969..0000000
--- a/host/windows/usb/legacy/driver/android_usb_interrupt_file_object.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
-#define ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbInterruptPipeFileObject
- that encapsulates extension to an interrupt pipe file objects.
-*/
-
-#include "android_usb_pipe_file_object.h"
-
-/** AndroidUsbInterruptPipeFileObject class encapsulates extension for a KMDF
- file object that represent opened interrupt pipe. Instances of this class
- must be allocated from NonPagedPool.
-*/
-class AndroidUsbInterruptPipeFileObject : public AndroidUsbPipeFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- @param wdf_pipe_obj[in] KMDF pipe for this file
- */
- AndroidUsbInterruptPipeFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbInterruptPipeFileObject();
-};
-
-#endif // ANDROID_USB_INTERRUPT_PIPE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_new_delete.h b/host/windows/usb/legacy/driver/android_usb_new_delete.h
deleted file mode 100755
index d1ca03b..0000000
--- a/host/windows/usb/legacy/driver/android_usb_new_delete.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_NEW_DELETE_H__
-#define ANDROID_USB_NEW_DELETE_H__
-/** \file
- This file consists implementations of our 'new' and 'delete' operators
-*/
-
-#include "android_usb_pool_tags.h"
-
-/** \brief Checks if given pool type is one of NonPaged pool kinds.
-
- All numeric values for all NonPaged pool types are even numbers while all
- numeric values for all PagedPool types are odd numbers (see definition of
- POOL_TYPE enum). So this routine utilizes this to see whether given pool
- type is one of NonPaged pool kinds. This routine can be called at any IRQL.
- @param pool_type[in] Pool type
- @return True if pool type is one of NonPaged pool types, false otherwise
-*/
-__forceinline bool IsPoolNonPaged(POOL_TYPE pool_type) {
- return (0 == (pool_type & 0x1));
-}
-
-/** @name Operators new and delete
-
- In Kernel Mode development each memory allocation must specify type of the
- pool from which memory should be allocated, usualy PagedPool or NonPagedPool.
- Because of that "traditional" operator 'new' that takes only one parameter
- (memory size) is not good so we modify that operator by adding two more
- parameters: pool type and memory tag (last one is optional but highly
- encouraged). To prevent from mistakes, traditional operator 'new' is also
- defined. It will allocate requested number of bytes from NonPagedPool with
- default memory tag but it will always assert on checked (debug) builds.
- Since there is no infrastructure for C++ exceptions in Kernel Mode we are
- not using them to report memory allocation error. So, on failure operators
- 'new' are returning NULL instead of throwing an exception.
-*/
-///@{
-
-/** \brief Main operator new
-
- This is the main operator new that allocates specified number of bytes from
- the specified pool and assigns a custom tag to the allocated memory.
- Inherits IRQL restrictions for ExAllocatePoolWithTag (see the DDK doc).
- @param size[in] Number of bytes to allocate.
- @param pool_type[in] Type of the pool to allocate from.
- @param pool_tag[in] A tag to attach to the allocated memory. Since utilities
- that display tags use their ASCII representations it's advisable to
- use tag values that are ASCII symbols, f.i. 'ATag'. Note that due to
- inversion of bytes in stored ULONG value, to read 'ATag' in the tag
- displaying utility, the actual value passed to operator 'new' must be
- 'gaTA'
- @return Pointer to allocated memory on success, NULL on error.
-*/
-__forceinline void* __cdecl operator new(size_t size,
- POOL_TYPE pool_type,
- ULONG pool_tag) {
- ASSERT((pool_type < MaxPoolType) && (0 != size));
- // Enforce IRQL restriction check.
- ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
- return size ? ExAllocatePoolWithTag(pool_type,
- static_cast<ULONG>(size),
- pool_tag) :
- NULL;
-}
-
-/** \brief
- Short operator new that attaches a default tag to the allocated memory.
-
- This version of operator new allocates specified number of bytes from the
- specified pool and assigns a default tag (GANDR_POOL_TAG_DEFAULT) to the
- allocated memory. Inherits IRQL restrictions for ExAllocatePoolWithTag.
- @param size[in] Number of bytes to allocate.
- @param pool_type[in] Type of the pool to allocate from.
- @return Pointer to allocated memory on success, NULL on error.
-*/
-__forceinline void* __cdecl operator new(size_t size, POOL_TYPE pool_type) {
- ASSERT((pool_type < MaxPoolType) && (0 != size));
- // Enforce IRQL restriction check.
- ASSERT(IsPoolNonPaged(pool_type) || (KeGetCurrentIrql() < DISPATCH_LEVEL));
- return size ? ExAllocatePoolWithTag(pool_type,
- static_cast<ULONG>(size),
- GANDR_POOL_TAG_DEFAULT) :
- NULL;
-}
-
-/** \brief Traditional operator new that should never be used.
-
- Using of this version of operator 'new' is prohibited in Kernel Mode
- development. For the sake of safety it is implemented though to allocate
- requested number of bytes from the NonPagedPool and attach default tag
- to the allocated memory. It will assert on checked (debug) builds.
- Inherits IRQL restrictions for ExAllocatePoolWithTag.
- @param size[in] Number of bytes to allocate.
- @return Pointer to memory allocated from NonPagedPool on success or NULL on
- error.
-*/
-__forceinline void* __cdecl operator new(size_t size) {
- ASSERTMSG("\n!!! Using of operator new(size_t size) is detected!\n"
- "This is illegal in our driver C++ development environment to use "
- "this version of operator 'new'. Please switch to\n"
- "new(size_t size, POOL_TYPE pool_type) or "
- "new(size_t size, POOL_TYPE pool_type, ULONG pool_tag) ASAP!!!\n",
- false);
- ASSERT(0 != size);
- return size ? ExAllocatePoolWithTag(NonPagedPool,
- static_cast<ULONG>(size),
- GANDR_POOL_TAG_DEFAULT) :
- NULL;
-}
-
-/** \brief Operator delete.
-
- Frees memory allocated by 'new' operator.
- @param pointer[in] Memory to free. If this parameter is NULL operator does
- nothing but asserts on checked build. Inherits IRQL restrictions
- for ExFreePool.
-*/
-__forceinline void __cdecl operator delete(void* pointer) {
- ASSERT(NULL != pointer);
- if (NULL != pointer)
- ExFreePool(pointer);
-}
-
-/** \brief Operator delete for arrays.
-
- Frees memory allocated by 'new' operator.
- @param pointer[in] Memory to free. If this parameter is NULL operator does
- nothing but asserts on checked build. Inherits IRQL restrictions
- for ExFreePool.
-*/
-__forceinline void __cdecl operator delete[](void* pointer) {
- ASSERT(NULL != pointer);
- if (NULL != pointer)
- ExFreePool(pointer);
-}
-
-///@}
-
-#endif // ANDROID_USB_NEW_DELETE_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.cpp b/host/windows/usb/legacy/driver/android_usb_pipe_file_object.cpp
deleted file mode 100755
index e696b37..0000000
--- a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.cpp
+++ /dev/null
@@ -1,738 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- This file consists of implementation of class AndroidUsbPipeFileObject that
- encapsulates a common extension for pipe file objects.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_pipe_file_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbPipeFileObject::AndroidUsbPipeFileObject(
- AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj)
- : AndroidUsbFileObject(AndroidUsbFileObjectTypePipe, dev_obj, wdf_fo),
- wdf_pipe_(wdf_pipe_obj) {
- ASSERT_IRQL_PASSIVE();
- ASSERT(NULL != wdf_pipe_obj);
-}
-
-#pragma code_seg()
-
-AndroidUsbPipeFileObject::~AndroidUsbPipeFileObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma code_seg("PAGE")
-
-NTSTATUS AndroidUsbPipeFileObject::InitializePipe(
- const WDF_USB_PIPE_INFORMATION* pipe_info) {
- ASSERT_IRQL_LOW();
- ASSERT(IsPipeAttached());
- if (!IsPipeAttached())
- return STATUS_INTERNAL_ERROR;
-
- // Initialize base class
- NTSTATUS status = AndroidUsbFileObject::Initialize();
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status))
- return status;
-
- // Save pipe information
- pipe_information_ = *pipe_info;
-
- // We will provide size check ourselves (less surprizes always better)
- WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(wdf_pipe());
-
- GoogleDbgPrint("\n===== File %p for %s pipe. max_transfer_size = %X, max_packet_size = %X",
- this, is_input_pipe() ? "read" : "write",
- max_transfer_size(), max_packet_size());
- return STATUS_SUCCESS;
-}
-
-#pragma code_seg()
-
-void AndroidUsbPipeFileObject::OnEvtIoRead(WDFREQUEST request,
- size_t length) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Make sure that this is an input pipe
- if (is_output_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to read from output pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Make sure zero length I/O doesn't go through
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- // Get MDL for this request.
- PMDL request_mdl = NULL;
- NTSTATUS status = WdfRequestRetrieveOutputWdmMdl(request, &request_mdl);
- ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
- if (NT_SUCCESS(status)) {
- CommonBulkReadWrite(request,
- request_mdl,
- static_cast<ULONG>(length),
- true,
- 0,
- false);
- } else {
- WdfRequestComplete(request, status);
- }
-}
-
-void AndroidUsbPipeFileObject::OnEvtIoWrite(WDFREQUEST request,
- size_t length) {
-
- // Make sure that this is an output pipe
- if (is_input_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to write to input pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Make sure zero length I/O doesn't go through
- if (0 == length) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- // Get MDL for this request.
- PMDL request_mdl = NULL;
- NTSTATUS status = WdfRequestRetrieveInputWdmMdl(request, &request_mdl);
- ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
- if (NT_SUCCESS(status)) {
- CommonBulkReadWrite(request,
- request_mdl,
- static_cast<ULONG>(length),
- false,
- 0,
- false);
- } else {
- WdfRequestComplete(request, status);
- }
-}
-
-void AndroidUsbPipeFileObject::OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- switch (ioctl_code) {
- case ADB_IOCTL_GET_ENDPOINT_INFORMATION:
- OnCtlGetEndpointInformation(request, output_buf_len);
- break;
-
- case ADB_IOCTL_BULK_READ:
- OnCtlBulkRead(request, output_buf_len, input_buf_len);
- break;
-
- case ADB_IOCTL_BULK_WRITE:
- OnCtlBulkWrite(request, output_buf_len, input_buf_len);
- break;
-
- default:
- AndroidUsbFileObject::OnEvtIoDeviceControl(request,
- output_buf_len,
- input_buf_len,
- ioctl_code);
- break;
- }
-}
-
-void AndroidUsbPipeFileObject::OnCtlGetEndpointInformation(
- WDFREQUEST request,
- size_t output_buf_len) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Verify output buffer
- if (output_buf_len < sizeof(AdbEndpointInformation)) {
- WdfRequestCompleteWithInformation(request,
- STATUS_BUFFER_TOO_SMALL,
- sizeof(AdbEndpointInformation));
- return;
- }
-
- // Get the output buffer
- NTSTATUS status;
- AdbEndpointInformation* ret_info =
- reinterpret_cast<AdbEndpointInformation*>(OutAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != ret_info));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Copy endpoint info to the output
- ret_info->max_packet_size = pipe_information_.MaximumPacketSize;
- ret_info->endpoint_address = pipe_information_.EndpointAddress;
- ret_info->polling_interval = pipe_information_.Interval;
- ret_info->setting_index = pipe_information_.SettingIndex;
- ret_info->endpoint_type =
- static_cast<AdbEndpointType>(pipe_information_.PipeType);
- ret_info->max_transfer_size = pipe_information_.MaximumTransferSize;
-
- WdfRequestCompleteWithInformation(request,
- STATUS_SUCCESS,
- sizeof(AdbEndpointInformation));
-}
-
-void AndroidUsbPipeFileObject::OnCtlBulkRead(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Make sure that this is an input pipe
- if (is_output_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to IOCTL read from output pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Make sure zero length I/O doesn't go through
- if (0 == output_buf_len) {
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 0);
- return;
- }
-
- // Verify buffers
- ASSERT(input_buf_len >= sizeof(AdbBulkTransfer));
- if (input_buf_len < sizeof(AdbBulkTransfer)) {
- WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
- return;
- }
-
- // Get the input buffer
- NTSTATUS status;
- AdbBulkTransfer* transfer_param =
- reinterpret_cast<AdbBulkTransfer*>(InAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != transfer_param));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Get MDL for this request.
- PMDL request_mdl = NULL;
- status = WdfRequestRetrieveOutputWdmMdl(request, &request_mdl);
- ASSERT(NT_SUCCESS(status) && (NULL != request_mdl));
- if (NT_SUCCESS(status)) {
- // Perform the read
- CommonBulkReadWrite(request,
- request_mdl,
- static_cast<ULONG>(output_buf_len),
- true,
- transfer_param->time_out,
- true);
- } else {
- WdfRequestComplete(request, status);
- }
-}
-
-void AndroidUsbPipeFileObject::OnCtlBulkWrite(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Make sure that this is an output pipe
- if (is_input_pipe()) {
- GoogleDbgPrint("\n!!!! Attempt to IOCTL write to input pipe %p", this);
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return;
- }
-
- // Verify buffers
- ASSERT(input_buf_len >= sizeof(AdbBulkTransfer));
- // Output buffer points to ULONG that receives number of transferred bytes
- ASSERT(output_buf_len >= sizeof(ULONG));
- if ((input_buf_len < sizeof(AdbBulkTransfer)) ||
- (output_buf_len < sizeof(ULONG))) {
- WdfRequestComplete(request, STATUS_INVALID_BUFFER_SIZE);
- return;
- }
-
- // Get the input buffer
- NTSTATUS status = STATUS_SUCCESS;
- AdbBulkTransfer* transfer_param =
- reinterpret_cast<AdbBulkTransfer*>(InAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != transfer_param));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Get the output buffer
- ULONG* ret_transfer =
- reinterpret_cast<ULONG*>(OutAddress(request, &status));
- ASSERT(NT_SUCCESS(status) && (NULL != ret_transfer));
- if (!NT_SUCCESS(status)) {
- WdfRequestComplete(request, status);
- return;
- }
-
- // Cache these param to prevent us from sudden change after we've chacked it.
- // This is common practice in protecting ourselves from malicious code:
- // 1. Never trust anything that comes from the User Mode.
- // 2. Never assume that anything that User Mode buffer has will remain
- // unchanged.
- void* transfer_buffer = transfer_param->GetWriteBuffer();
- ULONG transfer_size = transfer_param->transfer_size;
-
- // Make sure zero length I/O doesn't go through
- if (0 == transfer_size) {
- *ret_transfer = 0;
- WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, sizeof(ULONG));
- return;
- }
-
- // Make sure that buffer is not NULL
- ASSERT(NULL != transfer_buffer);
- if (NULL == transfer_buffer) {
- WdfRequestComplete(request, STATUS_INVALID_PARAMETER);
- return;
- }
-
- // At this point we are ready to build MDL for the user buffer.
- PMDL write_mdl =
- IoAllocateMdl(transfer_buffer, transfer_size, FALSE, FALSE, NULL);
- ASSERT(NULL != write_mdl);
- if (NULL == write_mdl) {
- WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
- return;
- }
-
- // Now we need to probe/lock this mdl
- __try {
- MmProbeAndLockPages(write_mdl,
- WdfRequestGetRequestorMode(request),
- IoReadAccess);
- status = STATUS_SUCCESS;
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- status = GetExceptionCode();
- ASSERTMSG("\n!!!!! AndroidUsbPipeFileObject::OnCtlBulkWrite exception",
- false);
- }
-
- if (!NT_SUCCESS(status)) {
- IoFreeMdl(write_mdl);
- WdfRequestComplete(request, status);
- return;
- }
-
- // Perform the write
- status = CommonBulkReadWrite(request,
- write_mdl,
- transfer_size,
- false,
- transfer_param->time_out,
- true);
- if (!NT_SUCCESS(status)) {
- // If CommonBulkReadWrite failed we need to unlock and free MDL here
- MmUnlockPages(write_mdl);
- IoFreeMdl(write_mdl);
- }
-}
-
-NTSTATUS AndroidUsbPipeFileObject::CommonBulkReadWrite(
- WDFREQUEST request,
- PMDL transfer_mdl,
- ULONG length,
- bool is_read,
- ULONG time_out,
- bool is_ioctl) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- ASSERT(IsPipeAttached());
- if (!IsPipeAttached()) {
- WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
- return STATUS_INVALID_DEVICE_STATE;
- }
-
- // Quick access check. Might be redundant though...
- ASSERT((is_read && is_input_pipe()) || (!is_read && is_output_pipe()));
- if ((is_read && is_output_pipe()) || (!is_read && is_input_pipe())) {
- WdfRequestComplete(request, STATUS_ACCESS_DENIED);
- return STATUS_ACCESS_DENIED;
- }
-
- // Set URB flags
- ULONG urb_flags = USBD_SHORT_TRANSFER_OK | (is_read ?
- USBD_TRANSFER_DIRECTION_IN :
- USBD_TRANSFER_DIRECTION_OUT);
-
- // Calculate transfer length for this stage.
- ULONG stage_len =
- (length > GetTransferGranularity()) ? GetTransferGranularity() : length;
-
- // Get virtual address that we're gonna use in the transfer.
- // We rely here on the fact that we're in the context of the calling thread.
- void* virtual_address = MmGetMdlVirtualAddress(transfer_mdl);
-
- // Allocate our private MDL for this address which we will use for the transfer
- PMDL new_mdl = IoAllocateMdl(virtual_address, length, FALSE, FALSE, NULL);
- ASSERT(NULL != new_mdl);
- if (NULL == new_mdl) {
- WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // Map the portion of user buffer that we're going to transfer at this stage
- // to our mdl.
- IoBuildPartialMdl(transfer_mdl, new_mdl, virtual_address, stage_len);
-
- // Allocate memory for URB and associate it with this request
- WDF_OBJECT_ATTRIBUTES mem_attrib;
- WDF_OBJECT_ATTRIBUTES_INIT(&mem_attrib);
- mem_attrib.ParentObject = request;
-
- WDFMEMORY urb_mem = NULL;
- PURB urb = NULL;
- NTSTATUS status =
- WdfMemoryCreate(&mem_attrib,
- NonPagedPool,
- GANDR_POOL_TAG_BULKRW_URB,
- sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
- &urb_mem,
- reinterpret_cast<PVOID*>(&urb));
- ASSERT(NT_SUCCESS(status) && (NULL != urb));
- if (!NT_SUCCESS(status)) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // Get USB pipe handle for our pipe and initialize transfer request for it
- USBD_PIPE_HANDLE usbd_pipe_hndl = usbd_pipe();
- ASSERT(NULL != usbd_pipe_hndl);
- if (NULL == usbd_pipe_hndl) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
- return STATUS_INTERNAL_ERROR;
- }
-
- // Initialize URB with request information
- UsbBuildInterruptOrBulkTransferRequest(
- urb,
- sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
- usbd_pipe_hndl,
- NULL,
- new_mdl,
- stage_len,
- urb_flags,
- NULL);
-
- // Build transfer request
- status = WdfUsbTargetPipeFormatRequestForUrb(wdf_pipe(),
- request,
- urb_mem,
- NULL);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status)) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, status);
- return status;
- }
-
- // Initialize our request context.
- AndroidUsbWdfRequestContext* context =
- GetAndroidUsbWdfRequestContext(request);
- ASSERT(NULL != context);
- if (NULL == context) {
- IoFreeMdl(new_mdl);
- WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
- return STATUS_INTERNAL_ERROR;
- }
-
- context->object_type = AndroidUsbWdfObjectTypeRequest;
- context->urb_mem = urb_mem;
- context->transfer_mdl = transfer_mdl;
- context->mdl = new_mdl;
- context->length = length;
- context->transfer_size = stage_len;
- context->num_xfer = 0;
- context->virtual_address = virtual_address;
- context->is_read = is_read;
- context->initial_time_out = time_out;
- context->is_ioctl = is_ioctl;
-
- // Set our completion routine
- WdfRequestSetCompletionRoutine(request,
- CommonReadWriteCompletionEntry,
- this);
-
- // Init send options (our timeout goes here)
- WDF_REQUEST_SEND_OPTIONS send_options;
- if (0 != time_out) {
- WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
- WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_MS(time_out));
- }
-
- // Timestamp first WdfRequestSend
- KeQuerySystemTime(&context->sent_at);
-
- // Send request asynchronously.
- if (WdfRequestSend(request, wdf_pipe_io_target(),
- (0 == time_out) ? WDF_NO_SEND_OPTIONS : &send_options)) {
- return STATUS_SUCCESS;
- }
-
- // Something went wrong here
- status = WdfRequestGetStatus(request);
- ASSERT(!NT_SUCCESS(status));
- GoogleDbgPrint("\n!!!!! CommonBulkReadWrite: WdfRequestGetStatus (is_read = %u) failed: %08X",
- is_read, status);
- WdfRequestCompleteWithInformation(request, status, 0);
-
- return status;
-}
-
-void AndroidUsbPipeFileObject::OnCommonReadWriteCompletion(
- WDFREQUEST request,
- PWDF_REQUEST_COMPLETION_PARAMS completion_params,
- AndroidUsbWdfRequestContext* context) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- NTSTATUS status = completion_params->IoStatus.Status;
- if (!NT_SUCCESS(status)){
- GoogleDbgPrint("\n========== Request completed with failure: %X", status);
- IoFreeMdl(context->mdl);
- // If this was IOCTL-originated write we must unlock and free
- // our transfer MDL.
- if (context->is_ioctl && !context->is_read) {
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- }
- WdfRequestComplete(request, status);
- return;
- }
-
- // Get our URB buffer
- PURB urb
- = reinterpret_cast<PURB>(WdfMemoryGetBuffer(context->urb_mem, NULL));
- ASSERT(NULL != urb);
-
- // Lets see how much has been transfered and update our counters accordingly
- ULONG bytes_transfered =
- urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
- // We expect writes to transfer entire packet
- ASSERT((bytes_transfered == context->transfer_size) || context->is_read);
- context->num_xfer += bytes_transfered;
- context->length -= bytes_transfered;
-
- // Is there anything left to transfer? Now, by the protocol we should
- // successfuly complete partial reads, instead of waiting on full set
- // of requested bytes being accumulated in the read buffer.
- if ((0 == context->length) || context->is_read) {
- status = STATUS_SUCCESS;
-
- // This was the last transfer
- if (context->is_ioctl && !context->is_read) {
- // For IOCTL-originated writes we have to return transfer size through
- // the IOCTL's output buffer.
- ULONG* ret_transfer =
- reinterpret_cast<ULONG*>(OutAddress(request, NULL));
- ASSERT(NULL != ret_transfer);
- if (NULL != ret_transfer)
- *ret_transfer = context->num_xfer;
- WdfRequestSetInformation(request, sizeof(ULONG));
-
- // We also must unlock / free transfer MDL
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- } else {
- // For other requests we report transfer size through the request I/O
- // completion status.
- WdfRequestSetInformation(request, context->num_xfer);
- }
- IoFreeMdl(context->mdl);
- WdfRequestComplete(request, status);
- return;
- }
-
- // There are something left for the transfer. Prepare for it.
- // Required to free any mapping made on the partial MDL and
- // reset internal MDL state.
- MmPrepareMdlForReuse(context->mdl);
-
- // Update our virtual address
- context->virtual_address =
- reinterpret_cast<char*>(context->virtual_address) + bytes_transfered;
-
- // Calculate size of this transfer
- ULONG stage_len =
- (context->length > GetTransferGranularity()) ? GetTransferGranularity() :
- context->length;
-
- IoBuildPartialMdl(context->transfer_mdl,
- context->mdl,
- context->virtual_address,
- stage_len);
-
- // Reinitialize the urb and context
- urb->UrbBulkOrInterruptTransfer.TransferBufferLength = stage_len;
- context->transfer_size = stage_len;
-
- // Format the request to send a URB to a USB pipe.
- status = WdfUsbTargetPipeFormatRequestForUrb(wdf_pipe(),
- request,
- context->urb_mem,
- NULL);
- ASSERT(NT_SUCCESS(status));
- if (!NT_SUCCESS(status)) {
- if (context->is_ioctl && !context->is_read) {
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- }
- IoFreeMdl(context->mdl);
- WdfRequestComplete(request, status);
- return;
- }
-
- // Reset the completion routine
- WdfRequestSetCompletionRoutine(request,
- CommonReadWriteCompletionEntry,
- this);
-
- // Send the request asynchronously.
- if (!WdfRequestSend(request, wdf_pipe_io_target(), WDF_NO_SEND_OPTIONS)) {
- if (context->is_ioctl && !context->is_read) {
- MmUnlockPages(context->transfer_mdl);
- IoFreeMdl(context->transfer_mdl);
- }
- status = WdfRequestGetStatus(request);
- IoFreeMdl(context->mdl);
- WdfRequestComplete(request, status);
- }
-}
-
-NTSTATUS AndroidUsbPipeFileObject::ResetPipe() {
- ASSERT_IRQL_PASSIVE();
-
- // This routine synchronously submits a URB_FUNCTION_RESET_PIPE
- // request down the stack.
- NTSTATUS status = WdfUsbTargetPipeAbortSynchronously(wdf_pipe(),
- WDF_NO_HANDLE,
- NULL);
- if (NT_SUCCESS(status)) {
- status = WdfUsbTargetPipeResetSynchronously(wdf_pipe(),
- WDF_NO_HANDLE,
- NULL);
- if (!NT_SUCCESS(status))
- GoogleDbgPrint("\n!!!!! AndroidUsbPipeFileObject::ResetPipe failed %X", status);
- } else {
- GoogleDbgPrint("\n!!!!! WdfUsbTargetPipeAbortSynchronously failed %X", status);
- }
-
- return status;
-}
-
-NTSTATUS AndroidUsbPipeFileObject::QueueResetPipePassiveCallback() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // Initialize workitem
- WDF_OBJECT_ATTRIBUTES attr;
- WDF_OBJECT_ATTRIBUTES_INIT(&attr);
- WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attr, AndroidUsbWorkitemContext);
- attr.ParentObject = wdf_device();
-
- WDFWORKITEM wdf_work_item = NULL;
- WDF_WORKITEM_CONFIG workitem_config;
- WDF_WORKITEM_CONFIG_INIT(&workitem_config, ResetPipePassiveCallbackEntry);
- NTSTATUS status = WdfWorkItemCreate(&workitem_config,
- &attr,
- &wdf_work_item);
- ASSERT(NT_SUCCESS(status) && (NULL != wdf_work_item));
- if (!NT_SUCCESS(status))
- return status;
-
- // Initialize our extension to work item
- AndroidUsbWorkitemContext* context =
- GetAndroidUsbWorkitemContext(wdf_work_item);
- ASSERT(NULL != context);
- if (NULL == context) {
- WdfObjectDelete(wdf_work_item);
- return STATUS_INTERNAL_ERROR;
- }
-
- context->object_type = AndroidUsbWdfObjectTypeWorkitem;
- context->pipe_file_ext = this;
-
- // Enqueue this work item.
- WdfWorkItemEnqueue(wdf_work_item);
-
- return STATUS_SUCCESS;
-}
-
-void AndroidUsbPipeFileObject::CommonReadWriteCompletionEntry(
- WDFREQUEST request,
- WDFIOTARGET wdf_target,
- PWDF_REQUEST_COMPLETION_PARAMS completion_params,
- WDFCONTEXT completion_context) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- AndroidUsbWdfRequestContext*
- context = GetAndroidUsbWdfRequestContext(request);
- ASSERT((NULL != context) && (AndroidUsbWdfObjectTypeRequest == context->object_type));
-
- AndroidUsbPipeFileObject* pipe_file_ext =
- reinterpret_cast<AndroidUsbPipeFileObject*>(completion_context);
- ASSERT((NULL != pipe_file_ext) &&
- (pipe_file_ext->wdf_pipe() == (WDFUSBPIPE)wdf_target));
-
- pipe_file_ext->OnCommonReadWriteCompletion(request,
- completion_params,
- context);
-}
-
-void AndroidUsbPipeFileObject::ResetPipePassiveCallbackEntry(
- WDFWORKITEM wdf_work_item) {
- ASSERT_IRQL_PASSIVE();
-
- AndroidUsbWorkitemContext* context =
- GetAndroidUsbWorkitemContext(wdf_work_item);
- ASSERT((NULL != context) &&
- (AndroidUsbWdfObjectTypeWorkitem == context->object_type));
- if ((NULL == context) ||
- (AndroidUsbWdfObjectTypeWorkitem != context->object_type)) {
- WdfObjectDelete(wdf_work_item);
- return;
- }
-
- // In the sample they reset the device if pipe reset failed
- AndroidUsbDeviceObject* wdf_device_ext =
- context->pipe_file_ext->device_object();
-
- NTSTATUS status = context->pipe_file_ext->ResetPipe();
- if (!NT_SUCCESS(status))
- status = wdf_device_ext->ResetDevice();
-
- WdfObjectDelete(wdf_work_item);
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.h b/host/windows/usb/legacy/driver/android_usb_pipe_file_object.h
deleted file mode 100755
index ce02d25..0000000
--- a/host/windows/usb/legacy/driver/android_usb_pipe_file_object.h
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_PIPE_FILE_OBJECT_H__
-#define ANDROID_USB_PIPE_FILE_OBJECT_H__
-/** \file
- This file consists of declaration of class AndroidUsbPipeFileObject that
- encapsulates a common extension for pipe file objects.
-*/
-
-#include "android_usb_file_object.h"
-
-/** AndroidUsbPipeFileObject class encapsulates extension for a KMDF file
- object that represents opened pipe. Instances of this class must be
- allocated from NonPagedPool.
-*/
-class AndroidUsbPipeFileObject : public AndroidUsbFileObject {
- public:
- /** \brief Constructs the object.
-
- This method must be called at low IRQL.
- @param dev_obj[in] Our device object for which this file has been created
- @param wdf_fo[in] KMDF file object this extension wraps
- @param wdf_pipe_obj[in] KMDF pipe for this file
- */
- AndroidUsbPipeFileObject(AndroidUsbDeviceObject* dev_obj,
- WDFFILEOBJECT wdf_fo,
- WDFUSBPIPE wdf_pipe_obj);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbPipeFileObject();
-
- /** \brief Initializes the pipe file object extension
-
- This method internally calls AndroidUsbFileObject::Initialize()
- This method must be called at low IRQL
- @param pipe_info[in] Pipe information
- @return STATUS_SUCCESS or an appropriate error code
- */
- virtual NTSTATUS InitializePipe(const WDF_USB_PIPE_INFORMATION* pipe_info);
-
- /** \brief Read event handler
-
- This method is called when a read request comes to the file object this
- extension wraps. This method is an override.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be read.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoRead(WDFREQUEST request, size_t length);
-
- /** \brief Write event handler
-
- This method is called when a write request comes to the file object this
- extension wraps. This method is an override.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param length[in] The number of bytes to be written.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoWrite(WDFREQUEST request, size_t length);
-
- /** \brief IOCTL event handler
-
- This method is called when a device control request comes to the file
- object this extension wraps. We hanlde the following IOCTLs here:
- 1. ADB_CTL_GET_ENDPOINT_INFORMATION
- 2. ADB_CTL_BULK_READ
- 3. ADB_CTL_BULK_WRITE
- This method can be called IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- @param ioctl_code[in] The driver-defined or system-defined I/O control code
- that is associated with the request.
- @return Successful status or an appropriate error code
- */
- virtual void OnEvtIoDeviceControl(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len,
- ULONG ioctl_code);
-
- protected:
- /** \brief Handler for ADB_CTL_GET_ENDPOINT_INFORMATION IOCTL request
-
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- */
- virtual void OnCtlGetEndpointInformation(WDFREQUEST request,
- size_t output_buf_len);
-
- /** \brief Handler for ADB_CTL_BULK_READ IOCTL request
-
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- */
- virtual void OnCtlBulkRead(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len);
-
- /** \brief Handler for ADB_CTL_BULK_WRITE IOCTL request
-
- @param request[in] A handle to a framework request object.
- @param output_buf_len[in] The length, in bytes, of the request's output
- buffer, if an output buffer is available.
- @param input_buf_len[in] The length, in bytes, of the request's input
- buffer, if an input buffer is available.
- */
- virtual void OnCtlBulkWrite(WDFREQUEST request,
- size_t output_buf_len,
- size_t input_buf_len);
-
- /** \brief Performs common bulk read / write on the pipe
-
- This method is called from bulk and interrupt pipe file extensions to
- perform read to / write from the pipe this file represents. Typicaly,
- this method is called from OnEvtIoRead / OnEvtIoWrite /
- OnEvtIoDeviceControl methods. One very special case for this method is
- IOCTL-originated write request. If this is IOCTL-originated write request
- we can't report transfer size through the request's status block. Instead,
- for IOCTL-originated writes, the output buffer must a) exist and b) point
- to an ULONG that will receive size of the transfer. Besides, for this type
- of writes we create / lock write buffer MDL ourselves so we need to unlock
- and free it in the completion routine.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object.
- @param transfer_mdl[in] MDL for the transferring buffer. The MDL must be
- locked prior to this call.
- @param length[in] The number of bytes to be read / written. If this method
- is actually IOCTL originated write request this parameter must be
- taken from AdbBulkTransfer.transfer_size by the caller of this
- method. AdbBulkTransfer is available at the beginning of the input
- buffer for bulk read / write IOCTLs.
- @param is_read[in] If true this is a read operation, otherwise it's write
- operation.
- @param time_out[in] Number of milliseconds for this request to complete.
- If this parameter is zero there will be no timeout associated with
- the request. Otherwise, if request doesn't complete within the given
- timeframe it will be cancelled.
- @param is_ioctl[in] If 'true' this method has been called from IOCTL
- handler. Otherwise it has been called from read / write handler. If
- this is IOCTL-originated write request we need to report bytes
- transferred through the IOCTL's output buffer.
- This method can be called IRQL <= DISPATCH_LEVEL.
- @return STATUS_SUCCESS or an appropriate error code
- */
- virtual NTSTATUS CommonBulkReadWrite(WDFREQUEST request,
- PMDL transfer_mdl,
- ULONG length,
- bool is_read,
- ULONG time_out,
- bool is_ioctl);
-
- /** \brief Handles request completion for CommonBulkReadWrite
-
- This method is called from CommonReadWriteCompletionEntry.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object that is being
- completed.
- @param params[in] A pointer to a WDF_REQUEST_COMPLETION_PARAMS structure
- that contains information about the completed request.
- @param context[in] Context associated with this request in
- CommonBulkReadWrite
- This method can be called IRQL <= DISPATCH_LEVEL.
- */
- virtual void OnCommonReadWriteCompletion(WDFREQUEST request,
- PWDF_REQUEST_COMPLETION_PARAMS completion_params,
- AndroidUsbWdfRequestContext* context);
-
- /** \brief Resets pipe associated with this file
-
- After reseting the pipe this object might be destroyed.
- This method must be called at PASSIVE IRQL.
- @param read_device_on_failure[in] If true and reset pipe has failed this
- method will attempt to reset the device.
- @return STATUS_SUCCESS on success or an appropriate error code
- */
- virtual NTSTATUS ResetPipe();
-
- /** \brief Queues a workitem to launch pipe reset at PASSIVE IRQL
-
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @return STATUS_SUCCESS or an appropriate error code.
- */
- virtual NTSTATUS QueueResetPipePassiveCallback();
-
- private:
- /** \brief Request completion routine for CommonBulkReadWrite
-
- This method can be called at IRQL <= DISPATCH_LEVEL.
- @param request[in] A handle to a framework request object that is being
- completed.
- @param wdf_target[in] A handle to an I/O target object that represents the
- I/O target that completed the request. In this case this is a pipe.
- @param params[in] A pointer to a WDF_REQUEST_COMPLETION_PARAMS structure
- that contains information about the completed request.
- @param completion_context[in] A handle to driver-supplied context
- information, which the driver specified in a previous call to
- WdfRequestSetCompletionRoutine. In our case this is a pointer
- to this class instance that issued the request.
- This method can be called IRQL <= DISPATCH_LEVEL.
- */
- static void CommonReadWriteCompletionEntry(WDFREQUEST request,
- WDFIOTARGET wdf_target,
- PWDF_REQUEST_COMPLETION_PARAMS params,
- WDFCONTEXT completion_context);
-
- /** \brief Entry point for pipe reset workitem callback
-
- This method is called at PASSIVE IRQL
- @param wdf_work_item[in] A handle to a framework work item object.
- */
- static void ResetPipePassiveCallbackEntry(WDFWORKITEM wdf_work_item);
-
- public:
- /// Gets KMDF pipe handle for this file
- __forceinline WDFUSBPIPE wdf_pipe() const {
- return wdf_pipe_;
- }
-
- /// Gets maximum transfer size for this pipe
- __forceinline ULONG max_transfer_size() const {
- ASSERT(0 != pipe_information_.MaximumTransferSize);
- return pipe_information_.MaximumTransferSize;
- }
-
- /// Gets maximum packet size this pipe is capable of
- __forceinline ULONG max_packet_size() const {
- ASSERT(0 != pipe_information_.MaximumPacketSize);
- return pipe_information_.MaximumPacketSize;
- }
-
- /// Gets transfer granularity
- // TODO: It looks like device USB is capable of handling
- // packets with size greater than pipe_information_.MaximumPacketSize!
- // So, looks like we are not bound by this parameter in this driver.
- __forceinline ULONG GetTransferGranularity() const {
- return max_transfer_size();
- }
-
- /// Checks if this is an input pipe
- __forceinline bool is_input_pipe() const {
- return WDF_USB_PIPE_DIRECTION_IN(pipe_information_.EndpointAddress) ?
- true : false;
- }
-
- /// Checks if this is an output pipe
- __forceinline bool is_output_pipe() const {
- return WDF_USB_PIPE_DIRECTION_OUT(pipe_information_.EndpointAddress) ?
- true : false;
- }
-
- /// Checks if pipe is attached to this file
- __forceinline bool IsPipeAttached() const {
- return (NULL != wdf_pipe());
- }
-
- /// Gets USBD pipe handle
- // TODO: Can we cache this?
- __forceinline USBD_PIPE_HANDLE usbd_pipe() const {
- ASSERT(IsPipeAttached());
- return (IsPipeAttached()) ? WdfUsbTargetPipeWdmGetPipeHandle(wdf_pipe()) :
- NULL;
- }
-
- /// Gets I/O target handle for this pipe
- // TODO: Can we cache this?
- __forceinline WDFIOTARGET wdf_pipe_io_target() const {
- ASSERT(IsPipeAttached());
- return (IsPipeAttached()) ? WdfUsbTargetPipeGetIoTarget(wdf_pipe()) :
- NULL;
- }
-
- protected:
- /// Cached pipe information
- WDF_USB_PIPE_INFORMATION pipe_information_;
-
- /// KMDF pipe handle for this file
- WDFUSBPIPE wdf_pipe_;
-};
-
-#endif // ANDROID_USB_PIPE_FILE_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_pool_tags.h b/host/windows/usb/legacy/driver/android_usb_pool_tags.h
deleted file mode 100755
index 7e52e84..0000000
--- a/host/windows/usb/legacy/driver/android_usb_pool_tags.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_POOL_TAGS_H__
-#define ANDROID_USB_POOL_TAGS_H__
-/** \file
- This file consists definitions for pool tags used in memory allocations for
- the driver.
-*/
-
-/// Default pool tag for memory allocations (GAND)
-#define GANDR_POOL_TAG_DEFAULT 'DNAG'
-
-/// Pool tag for the driver object (GADR)
-#define GANDR_POOL_TAG_DRIVER_OBJECT 'RDAG'
-
-/// Pool tag for KMDF device object extension (GADx)
-#define GANDR_POOL_TAG_KMDF_DEVICE 'xDAG'
-
-/// Pool tag for target device configuration descriptor (GACD)
-#define GANDR_POOL_TAG_DEV_CFG_DESC 'DCAG'
-
-/// Pool tag for device file object extension (GADf)
-#define GANDR_POOL_TAG_DEVICE_FO 'fDAG'
-
-/// Pool tag for a bulk file object extension (GABx)
-#define GANDR_POOL_TAG_BULK_FILE 'xBAG'
-
-/// Pool tag for an interrupt file object extension (GAIx)
-#define GANDR_POOL_TAG_INTERRUPT_FILE 'xIAG'
-
-/// Pool tag for URB allocated in bulk read / write (GAbu)
-#define GANDR_POOL_TAG_BULKRW_URB 'ubAG'
-
-/// Pool tag for interface pairs (GAip)
-#define GANDR_POOL_TAG_INTERF_PAIRS 'piAG'
-
-#endif // ANDROID_USB_POOL_TAGS_H__
diff --git a/host/windows/usb/legacy/driver/android_usb_wdf_object.cpp b/host/windows/usb/legacy/driver/android_usb_wdf_object.cpp
deleted file mode 100755
index 7210be6..0000000
--- a/host/windows/usb/legacy/driver/android_usb_wdf_object.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- This file consists of implementation of a class AndroidUsbWdfObject that
- encapsulates a basic extension to all KMDF objects. Currently, device and
- file object extensions ared derived from it.
-*/
-#pragma data_seg()
-#pragma code_seg()
-
-#include "precomp.h"
-#include "android_usb_wdf_object.h"
-
-#pragma data_seg()
-#pragma code_seg("PAGE")
-
-AndroidUsbWdfObject::AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type)
- : wdf_object_(NULL),
- object_type_(obj_type) {
- ASSERT_IRQL_LOW();
- ASSERT(obj_type < AndroidUsbWdfObjectTypeMax);
-}
-
-#pragma code_seg()
-
-AndroidUsbWdfObject::~AndroidUsbWdfObject() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-}
-
-#pragma code_seg("PAGE")
-
-NTSTATUS AndroidUsbWdfObject::InitObjectAttributes(
- PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,
- WDFOBJECT parent) {
- ASSERT_IRQL_LOW();
-
- // Enforce file object extension exception.
- ASSERT(!Is(AndroidUsbWdfObjectTypeFile));
- if (Is(AndroidUsbWdfObjectTypeFile))
- return STATUS_INTERNAL_ERROR;
-
- // Initialize attributes and set cleanup and destroy callbacks
- WDF_OBJECT_ATTRIBUTES_INIT(wdf_obj_attr);
- WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(wdf_obj_attr,
- AndroidUsbWdfObjectContext);
- wdf_obj_attr->EvtCleanupCallback = EvtCleanupCallbackEntry;
- wdf_obj_attr->EvtDestroyCallback = EvtDestroyCallbackEntry;
- wdf_obj_attr->ParentObject = parent;
- wdf_obj_attr->SynchronizationScope = GetWdfSynchronizationScope();
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS AndroidUsbWdfObject::InitializeContext() {
- ASSERT_IRQL_LOW();
- ASSERT(IsAttached());
- if (!IsAttached())
- return STATUS_INTERNAL_ERROR;
-
- // Initialize our extension to that object
- AndroidUsbWdfObjectContext* context =
- GetAndroidUsbWdfObjectContext(wdf_object());
- ASSERT(NULL != context);
- if (NULL == context)
- return STATUS_INTERNAL_ERROR;
-
- // Make sure that extension has not been initialized
- ASSERT((0 == context->object_type) && (NULL == context->wdf_object_ext));
- if ((0 != context->object_type) || (NULL != context->wdf_object_ext))
- return STATUS_INTERNAL_ERROR;
-
- context->object_type = object_type();
- context->wdf_object_ext = this;
- ASSERT(this == GetAndroidUsbWdfObjectFromHandle(wdf_object()));
-
- return STATUS_SUCCESS;
-}
-
-#pragma code_seg()
-
-WDF_SYNCHRONIZATION_SCOPE AndroidUsbWdfObject::GetWdfSynchronizationScope() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- // By default we don't want KMDF to synchronize access to our objects
- return WdfSynchronizationScopeNone;
-}
-
-void AndroidUsbWdfObject::OnEvtCleanupCallback() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- GoogleDbgPrint("\n----- Object %p of type %u is cleaned up",
- this, object_type());
-}
-
-void AndroidUsbWdfObject::OnEvtDestroyCallback() {
- ASSERT_IRQL_LOW_OR_DISPATCH();
- GoogleDbgPrint("\n----- Object %p of type %u is destroyed",
- this, object_type());
-}
-
-void AndroidUsbWdfObject::EvtCleanupCallbackEntry(WDFOBJECT wdf_obj) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- AndroidUsbWdfObjectContext* context = GetAndroidUsbWdfObjectContext(wdf_obj);
- ASSERT(NULL != context);
- if (NULL != context) {
- // For file objects we will be always called here even though we didn't
- // create any extension for them. In this case the context must not be
- // initialized.
- ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) ||
- ((0 != context->object_type) && (NULL != context->wdf_object_ext)));
- if (NULL != context->wdf_object_ext) {
- ASSERT(context->wdf_object_ext->Is(context->object_type));
- context->wdf_object_ext->OnEvtCleanupCallback();
- }
- }
-}
-
-void AndroidUsbWdfObject::EvtDestroyCallbackEntry(WDFOBJECT wdf_obj) {
- ASSERT_IRQL_LOW_OR_DISPATCH();
-
- AndroidUsbWdfObjectContext* context =
- GetAndroidUsbWdfObjectContext(wdf_obj);
- ASSERT(NULL != context);
- if (NULL != context) {
- // For file objects we will be always called here even though we didn't
- // create any extension for them. In this case the context must not be
- // initialized.
- ASSERT(((0 == context->object_type) && (NULL == context->wdf_object_ext)) ||
- ((0 != context->object_type) && (NULL != context->wdf_object_ext)));
- if (NULL != context->wdf_object_ext) {
- ASSERT(context->wdf_object_ext->Is(context->object_type));
- context->wdf_object_ext->OnEvtDestroyCallback();
- delete context->wdf_object_ext;
- }
- }
-}
-
-#pragma data_seg()
-#pragma code_seg()
diff --git a/host/windows/usb/legacy/driver/android_usb_wdf_object.h b/host/windows/usb/legacy/driver/android_usb_wdf_object.h
deleted file mode 100755
index d5e814c..0000000
--- a/host/windows/usb/legacy/driver/android_usb_wdf_object.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef ANDROID_USB_WDF_OBJECT_H__
-#define ANDROID_USB_WDF_OBJECT_H__
-/** \file
- This file consists of declaration of a class AndroidUsbWdfObject that
- encapsulates a basic extension to all KMDF objects. Currently, device and
- file object extensions ared derived from it.
-*/
-
-/** AndroidUsbWdfObject class encapsulates a basic extension to all KMDF
- objects. Currently, device and file object extensions ared derived from it.
- Instances of this and derived classes must be allocated from NonPagedPool.
-*/
-class AndroidUsbWdfObject {
- public:
- /** \brief Constructs the object.
-
- @param obj_type[in] Type of the object that this wrapper represents.
- This method must be called at low IRQL.
- */
- AndroidUsbWdfObject(AndroidUsbWdfObjectType obj_type);
-
- /** \brief Destructs the object.
-
- This method can be called at any IRQL.
- */
- virtual ~AndroidUsbWdfObject();
-
- /** \brief Initializes object attributes for new KMDF object.
-
- Each KMDF extension object must perform attribute initializations in order
- to register an extension with KMDF framework. Since all our extensions are
- derived from the base AndroidUsbWdfObject we use a single WDF object
- extension context for all KMDF objects that we extend. So we can initialize
- and register our context extension structure here. Note that object
- attributes for file object wrappers are initialized globaly, when device
- object is created. So file object extensions must not call this method.
- This method must be called at low IRQL.
- @param wdf_obj_attr[out] Object attributes to initialize.
- @param parent[in] Parent object for this object. Can be NULL.
- @return STATUS_SUCCESS on success or an appropriate error code.
- */
- virtual NTSTATUS InitObjectAttributes(PWDF_OBJECT_ATTRIBUTES wdf_obj_attr,
- WDFOBJECT parent);
-
- /** \brief Initializes context for this extension
-
- This method initializes AndroidUsbWdfObjectContext structure that KMDF
- allocated for the object that is being extended with this class.
- InitObjectAttributes method must be called prior to the call to this
- method. Besides, before calling this method, instance of this class must
- be already attached to the KMDF object it represents. Otherwise this
- method will fail with STATUS_INTERNAL_ERROR.
- This method must be called at low IRQL.
- @return STATUS_SUCCESS on success or an appropriate error code
- */
- virtual NTSTATUS InitializeContext();
-
-
- protected:
- /** \brief Returns syncronisation scope for this extension type.
-
- This method is called from InitObjectAttributes method to specify what
- type of synchronization is required for instances of this type. By
- default we return WdfSynchronizationScopeNone which makes KMDF not
- to synchronize access to this type of object.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- */
- virtual WDF_SYNCHRONIZATION_SCOPE GetWdfSynchronizationScope();
-
- /** \brief Handler for cleanup event fired for associated KMDF object.
-
- The framework calls this callback function when either the framework or a
- driver attempts to delete the object.
- This method can be called at IRQL <= DISPATCH_LEVEL.
- */
- virtual void OnEvtCleanupCallback();
-
- /** \brief Handler for destroy callback
-
- The framework calls the EvtDestroyCallback callback function after the
- object's reference count has been decremented to zero. The framework
- deletes the object immediately after the EvtDestroyCallback callback
- function returns.
- This callback can be called at IRQL <= DISPATCH_LEVEL.
- */
- virtual void OnEvtDestroyCallback();
-
- /** \brief Removes driver's references on an object so it can be deleted.
-
- The framework calls the callback function when either the framework or a
- driver attempts to delete the object.
- This callback can be called at IRQL <= DISPATCH_LEVEL.
- @param wdf_obj[in] A handle to a framework object this class wraps.
- */
- static void EvtCleanupCallbackEntry(WDFOBJECT wdf_obj);
-
- /** \brief Called when framework object is being deleted
-
- The framework calls the EvtDestroyCallback callback function after the
- object's reference count has been decremented to zero. The framework
- deletes the object immediately after the EvtDestroyCallback callback
- function returns.
- This callback can be called at IRQL <= DISPATCH_LEVEL.
- @param wdf_obj[in] A handle to a framework object this class wraps.
- */
- static void EvtDestroyCallbackEntry(WDFOBJECT wdf_obj);
-
- public:
-
- /// Gets KMDF object extended with this instance
- __forceinline WDFOBJECT wdf_object() const {
- return wdf_object_;
- }
-
- /// Sets KMDF object associated with this extension
- __forceinline void set_wdf_object(WDFOBJECT wdf_obj) {
- ASSERT(NULL == wdf_object_);
- wdf_object_ = wdf_obj;
- }
-
- /// Gets KMDF object type for this extension
- __forceinline AndroidUsbWdfObjectType object_type() const {
- return object_type_;
- }
-
- /** \brief Checks if this extension represends KMDF object of the given type
-
- @param obj_type[in] Object type to check
- @return true if this wrapper represents object of that type and
- false otherwise.
- */
- __forceinline Is(AndroidUsbWdfObjectType obj_type) const {
- return (obj_type == object_type());
- }
-
- /// Checks if extension is attached to a KMDF object
- __forceinline bool IsAttached() const {
- return (NULL != wdf_object());
- }
-
- protected:
- /// KMDF object that is extended with this instance
- WDFOBJECT wdf_object_;
-
- /// KMDF object type for this extension
- AndroidUsbWdfObjectType object_type_;
-};
-
-/** \brief Gets our extension for the given KMDF object
-
- This method can be called at any IRQL
- @param wdf_obj[in] KMDF handle describing an object
- @return Instance of AndroidUsbWdfObject associated with this object or NULL
- if association is not found.
-*/
-__forceinline AndroidUsbWdfObject* GetAndroidUsbWdfObjectFromHandle(
- WDFOBJECT wdf_obj) {
- ASSERT(NULL != wdf_obj);
- if (NULL != wdf_obj) {
- AndroidUsbWdfObjectContext* context =
- GetAndroidUsbWdfObjectContext(wdf_obj);
- ASSERT((NULL != context) && (NULL != context->wdf_object_ext) &&
- (context->wdf_object_ext->Is(context->object_type)));
- if ((NULL != context) && (NULL != context->wdf_object_ext) &&
- context->wdf_object_ext->Is(context->object_type)) {
- return context->wdf_object_ext;
- }
- }
- return NULL;
-}
-
-#endif // ANDROID_USB_WDF_OBJECT_H__
diff --git a/host/windows/usb/legacy/driver/makefile b/host/windows/usb/legacy/driver/makefile
deleted file mode 100755
index 54a4d7b..0000000
--- a/host/windows/usb/legacy/driver/makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-!IF 0
-
-Copyright (C) 2006 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.
-
-Module Name:
-
- makefile.
-
-Notes:
-
- DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
- file to this component. This file merely indirects to the real make file
- that is shared by all the components of Windows NT (DDK)
-
-!ENDIF
-
-!if "$(DDK_TARGET_OS)"=="Win2K"
-!message This driver is not intended to target the Windows 2000 platform.
-!elseif "$(DDK_TARGET_OS)"=="WinNET"
-!INCLUDE $(NTMAKEENV)\makefile.def
-!else
-!INCLUDE $(NTMAKEENV)\makefile.def
-!endif
-
diff --git a/host/windows/usb/legacy/driver/makefile.inc b/host/windows/usb/legacy/driver/makefile.inc
deleted file mode 100755
index ca0dbd3..0000000
--- a/host/windows/usb/legacy/driver/makefile.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-_LNG=$(LANGUAGE)
-_INX=.
-STAMP=stampinf -f $@ -a $(_BUILDARCH)
-
-$(OBJ_PATH)\$(O)\$(INF_NAME).inf: $(_INX)\$(INF_NAME).inx
- copy $(_INX)\$(@B).inx $@
- $(STAMP)
diff --git a/host/windows/usb/legacy/driver/precomp.h b/host/windows/usb/legacy/driver/precomp.h
deleted file mode 100755
index bc798bc..0000000
--- a/host/windows/usb/legacy/driver/precomp.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-/** \file
- Standard precompile file
-*/
-#pragma warning(disable:4200)
-#pragma warning(disable:4201) // nameless struct/union
-#pragma warning(disable:4214) // bit field types other than int
-extern "C" {
-#include <initguid.h>
-#include <ntddk.h>
-#include <ntintsafe.h>
-#include <ntstrsafe.h>
-#include "usbdi.h"
-#include "usbdlib.h"
-#include <wdf.h>
-#include <wdfusb.h>
-} // extern "C"
-#pragma warning(default:4200)
-#pragma warning(default:4201)
-#pragma warning(default:4214)
-
-// Just to make adb_api.h compile. Since we will not reference any
-// of the API routines in the driver, only structures and constants,
-// we're fine with that.
-typedef void* LPOVERLAPPED;
-
-#include "adb_api.h"
-#include "adb_api_legacy.h"
-#include "android_usb_pool_tags.h"
-#include "android_usb_driver_defines.h"
-#include "android_usb_new_delete.h"
-#include "android_usb_inl.h"
diff --git a/host/windows/usb/legacy/driver/sources b/host/windows/usb/legacy/driver/sources
deleted file mode 100755
index 20dcc18..0000000
--- a/host/windows/usb/legacy/driver/sources
+++ /dev/null
@@ -1,32 +0,0 @@
-!IF 0
-
-Copyright (C) 2007 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.
-
-Module Name:
-
- sources.
-
-Abstract:
-
- This file specifies the target component being built and the list of
- sources files needed to build that component. Also specifies optional
- compiler switches and libraries that are unique for the component being
- built.
-
-!ENDIF
-
-!include sources.inc
-
-SOURCES= $(MOST_SOURCES) android_usb.rc
diff --git a/host/windows/usb/legacy/driver/sources.inc b/host/windows/usb/legacy/driver/sources.inc
deleted file mode 100755
index 7aeec1d..0000000
--- a/host/windows/usb/legacy/driver/sources.inc
+++ /dev/null
@@ -1,83 +0,0 @@
-!IF 0
-
-Copyright (C) 2007 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.
-
-Module Name:
-
- sources.
-
-Abstract:
-
- This file specifies the target component being built and the list of
- sources files needed to build that driver. Also specifies optional
- compiler switches and libraries that are unique for the component being
- built.
-
-!ENDIF
-
-TARGETNAME=androidusb
-!IF "$(DDKBUILDENV)"=="chk"
-TARGETPATH=..\build\Debug
-!ELSE
-TARGETPATH=..\build\Release
-!ENDIF
-TARGETTYPE=DRIVER
-KMDF_VERSION=1
-USECXX_FLAG=/TP
-USER_C_FLAGS=$(USER_C_FLAGS) /wd4100 /wd4002 /wd4509 /wd4390 /TP
-
-INCLUDES=$(INCLUDES); \
- $(IFSKIT_INC_PATH); \
- ..\..\api;
-
-TARGETLIBS=$(DDK_LIB_PATH)\usbd.lib
-
-MSC_WARNING_LEVEL=/W4 /WX /Wp64
-MSC_OPTIMIZATION = /Oi /Ob1
-C_DEFINES=$(C_DEFINES) -DEXPLODE_POOLTAGS -DRTL_USE_AVL_TABLES
-
-RCOPTIONS=$(RCOPTIONS) /dVER_COMPANYNAME_STR="\"Google Inc\""
-RCOPTIONS=$(RCOPTIONS) /dVER_LEGALCOPYRIGHT_YEARS="\"2007\""
-RCOPTIONS=$(RCOPTIONS) /dVER_LEGALCOPYRIGHT_STR="\"\251 Google Inc. All rights reserved.\""
-RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTNAME_STR="\"Google Android USB Driver\""
-RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTVERSION="1,00,01,001"
-RCOPTIONS=$(RCOPTIONS) /dVER_PRODUCTVERSION_STR="\"1.00\""
-
-!IF 0
-
-By overriding .rsrc section properties (!D removes Discardable attribute)
-we make sure that all our vtables will be placed properly into non-discardable
-data segment. Because of the nature of this driver we don't need to have
-vtables in NonPaged data sections because all our objects can be paged.
-Otherwise we may want to add /SECTION:.rsrc,X option that locks section in memory
-
-!ENDIF
-
-LINKER_FLAGS=$(LINKER_FLAGS) /MAP /MAPINFO:LINES /SECTION:.rsrc,!D
-
-MOST_SOURCES= \
- android_usb_driver_object.cpp \
- android_usb_wdf_object.cpp \
- android_usb_device_object.cpp \
- android_usb_file_object.cpp \
- android_usb_device_file_object.cpp \
- android_usb_pipe_file_object.cpp \
- android_usb_bulk_file_object.cpp \
- android_usb_interrupt_file_object.cpp
-
-PRECOMPILED_INCLUDE=precomp.h
-PRECOMPILED_PCH=precomp.pch
-PRECOMPILED_OBJ=precomp.obj
-
diff --git a/host/windows/usb/legacy/prebuilt/driver/WdfCoInstaller01005.dll b/host/windows/usb/legacy/prebuilt/driver/WdfCoInstaller01005.dll
deleted file mode 100644
index 12d2768..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/WdfCoInstaller01005.dll
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver/android_usb.inf b/host/windows/usb/legacy/prebuilt/driver/android_usb.inf
deleted file mode 100644
index fff0440..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/android_usb.inf
+++ /dev/null
@@ -1,126 +0,0 @@
-;/*++
-;
-;Abstract:
-; Installation inf for the Android USB Bulk device
-;
-;--*/
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=USB
-ClassGuid={F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}
-Provider=%GOOG%
-DriverVer=1/29/2009,1.0.0010.00000
-CatalogFile.NTx86=androidusb86.cat
-CatalogFile.NTamd64=androidusba64.cat
-
-; ================= Class section =====================
-
-[ClassInstall32]
-Addreg=AndroidUsbClassReg
-
-[AndroidUsbClassReg]
-HKR,,,0,%ClassName%
-HKR,,Icon,,-5
-
-[DestinationDirs]
-DefaultDestDir = 12
-
-; ================= Device section =====================
-
-[Manufacturer]
-%MfgName%=Google,NTx86,NTamd64
-
-; For Win2K
-[Google]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For XP and later
-[Google.NTx86]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For AMD64 and later
-[Google.NTamd64]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-[androidusb.Dev.NT]
-CopyFiles=androidusb.Files.Ext
-
-[androidusb.Dev.NT.Services]
-Addservice = androidusb, 0x00000002, androidusb.AddService
-
-[androidusb.AddService]
-DisplayName = %androidusb.SvcDesc%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %10%\System32\Drivers\androidusb.sys
-AddReg = androidusb.AddReg
-LoadOrderGroup = Base
-
-[androidusb.AddReg]
-HKR,"Parameters","MaximumTransferSize",0x10001,4096
-HKR,"Parameters","DebugLevel",0x10001,2
-HKR, Parameters\Wdf, VerboseOn, 0x00010001, 1
-HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
-HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
-
-[androidusb.Files.Ext]
-androidusb.sys
-
-[SourceDisksNames]
-1=%Disk_Description%,,,
-
-[SourceDisksFiles]
-androidusb.sys = 1
-
-;-------------- WDF Coinstaller installation
-[DestinationDirs]
-CoInstaller_CopyFiles = 11
-
-[androidusb.Dev.NT.CoInstallers]
-AddReg=CoInstaller_AddReg
-CopyFiles=CoInstaller_CopyFiles
-
-[CoInstaller_CopyFiles]
-wdfcoinstaller01005.dll
-
-[SourceDisksFiles]
-wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames
-
-[CoInstaller_AddReg]
-HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01005.dll,WdfCoInstaller"
-
-[androidusb.Dev.NT.Wdf]
-KmdfService = androidusb, androidusb_wdfsect
-
-[androidusb_wdfsect]
-KmdfLibraryVersion = 1.5
-
-;---------------------------------------------------------------;
-
-[Strings]
-GOOG = "Google, Inc"
-MfgName = "Google, Inc"
-Disk_Description= "ADB Interface Installation Disk"
-androidusb.SvcDesc = "ADB Interface Driver"
-ClassName = "ADB Interface"
-USB\VID_18D1&PID_DDDD.DeviceDescTest="ADB Testing Interface"
-USB\VID_0BB4&PID_0C01.DeviceDescRelease="HTC Dream"
-USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease="HTC Dream Composite ADB Interface"
-USB\VID_0BB4&PID_0FFF.DeviceDescRelease="HTC Bootloader"
diff --git a/host/windows/usb/legacy/prebuilt/driver/androidusb.sys b/host/windows/usb/legacy/prebuilt/driver/androidusb.sys
deleted file mode 100644
index fe64531..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/androidusb.sys
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver/androidusb86.cat b/host/windows/usb/legacy/prebuilt/driver/androidusb86.cat
deleted file mode 100644
index 12836dc..0000000
--- a/host/windows/usb/legacy/prebuilt/driver/androidusb86.cat
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/WdfCoInstaller01005.dll b/host/windows/usb/legacy/prebuilt/driver_amd_64/WdfCoInstaller01005.dll
deleted file mode 100644
index 32519fb..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/WdfCoInstaller01005.dll
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/android_usb.inf b/host/windows/usb/legacy/prebuilt/driver_amd_64/android_usb.inf
deleted file mode 100644
index fff0440..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/android_usb.inf
+++ /dev/null
@@ -1,126 +0,0 @@
-;/*++
-;
-;Abstract:
-; Installation inf for the Android USB Bulk device
-;
-;--*/
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=USB
-ClassGuid={F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}
-Provider=%GOOG%
-DriverVer=1/29/2009,1.0.0010.00000
-CatalogFile.NTx86=androidusb86.cat
-CatalogFile.NTamd64=androidusba64.cat
-
-; ================= Class section =====================
-
-[ClassInstall32]
-Addreg=AndroidUsbClassReg
-
-[AndroidUsbClassReg]
-HKR,,,0,%ClassName%
-HKR,,Icon,,-5
-
-[DestinationDirs]
-DefaultDestDir = 12
-
-; ================= Device section =====================
-
-[Manufacturer]
-%MfgName%=Google,NTx86,NTamd64
-
-; For Win2K
-[Google]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For XP and later
-[Google.NTx86]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-; For AMD64 and later
-[Google.NTamd64]
-; For loopback testing
-%USB\VID_18D1&PID_DDDD.DeviceDescTest%=androidusb.Dev, USB\VID_18D1&PID_DDDD
-; HTC Dream
-%USB\VID_0BB4&PID_0C01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C01
-%USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0C02&MI_01
-%USB\VID_0BB4&PID_0FFF.DeviceDescRelease%=androidusb.Dev, USB\VID_0BB4&PID_0FFF
-
-[androidusb.Dev.NT]
-CopyFiles=androidusb.Files.Ext
-
-[androidusb.Dev.NT.Services]
-Addservice = androidusb, 0x00000002, androidusb.AddService
-
-[androidusb.AddService]
-DisplayName = %androidusb.SvcDesc%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %10%\System32\Drivers\androidusb.sys
-AddReg = androidusb.AddReg
-LoadOrderGroup = Base
-
-[androidusb.AddReg]
-HKR,"Parameters","MaximumTransferSize",0x10001,4096
-HKR,"Parameters","DebugLevel",0x10001,2
-HKR, Parameters\Wdf, VerboseOn, 0x00010001, 1
-HKR, Parameters\Wdf, VerifierOn, 0x00010001, 1
-HKR, Parameters\Wdf, DbgBreakOnError, 0x00010001, 1
-
-[androidusb.Files.Ext]
-androidusb.sys
-
-[SourceDisksNames]
-1=%Disk_Description%,,,
-
-[SourceDisksFiles]
-androidusb.sys = 1
-
-;-------------- WDF Coinstaller installation
-[DestinationDirs]
-CoInstaller_CopyFiles = 11
-
-[androidusb.Dev.NT.CoInstallers]
-AddReg=CoInstaller_AddReg
-CopyFiles=CoInstaller_CopyFiles
-
-[CoInstaller_CopyFiles]
-wdfcoinstaller01005.dll
-
-[SourceDisksFiles]
-wdfcoinstaller01005.dll=1 ; make sure the number matches with SourceDisksNames
-
-[CoInstaller_AddReg]
-HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01005.dll,WdfCoInstaller"
-
-[androidusb.Dev.NT.Wdf]
-KmdfService = androidusb, androidusb_wdfsect
-
-[androidusb_wdfsect]
-KmdfLibraryVersion = 1.5
-
-;---------------------------------------------------------------;
-
-[Strings]
-GOOG = "Google, Inc"
-MfgName = "Google, Inc"
-Disk_Description= "ADB Interface Installation Disk"
-androidusb.SvcDesc = "ADB Interface Driver"
-ClassName = "ADB Interface"
-USB\VID_18D1&PID_DDDD.DeviceDescTest="ADB Testing Interface"
-USB\VID_0BB4&PID_0C01.DeviceDescRelease="HTC Dream"
-USB\VID_0BB4&PID_0C02&MI_01.DeviceDescRelease="HTC Dream Composite ADB Interface"
-USB\VID_0BB4&PID_0FFF.DeviceDescRelease="HTC Bootloader"
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusb.sys b/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusb.sys
deleted file mode 100644
index 70ce24f..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusb.sys
+++ /dev/null
Binary files differ
diff --git a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusba64.cat b/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusba64.cat
deleted file mode 100644
index dd7850d..0000000
--- a/host/windows/usb/legacy/prebuilt/driver_amd_64/androidusba64.cat
+++ /dev/null
Binary files differ
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index a4d511e..debf9a1 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -10,12 +10,14 @@
<classpathentry kind="src" path="packages/apps/Contacts/src"/>
<classpathentry kind="src" path="packages/apps/DeskClock/src"/>
<classpathentry kind="src" path="packages/apps/Email/src"/>
+ <classpathentry kind="src" path="packages/apps/Gallery3D/src"/>
<classpathentry kind="src" path="packages/apps/HTMLViewer/src"/>
<classpathentry kind="src" path="packages/apps/Launcher2/src"/>
<classpathentry kind="src" path="packages/apps/Mms/src"/>
<classpathentry kind="src" path="packages/apps/PackageInstaller/src"/>
<classpathentry kind="src" path="packages/apps/Phone/src"/>
<classpathentry kind="src" path="packages/apps/QuickSearchBox/src"/>
+ <classpathentry kind="src" path="packages/apps/Provision/src"/>
<classpathentry kind="src" path="packages/apps/Settings/src"/>
<classpathentry kind="src" path="packages/apps/SoundRecorder/src"/>
<classpathentry kind="src" path="packages/apps/Stk/src"/>
@@ -32,7 +34,6 @@
<classpathentry kind="src" path="frameworks/base/cmds/input/src"/>
<classpathentry kind="src" path="frameworks/base/cmds/pm/src"/>
<classpathentry kind="src" path="frameworks/base/cmds/svc/src"/>
- <classpathentry kind="src" path="frameworks/base/common/java"/>
<classpathentry kind="src" path="frameworks/base/core/java"/>
<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
<classpathentry kind="src" path="frameworks/base/graphics/java"/>
@@ -50,6 +51,7 @@
<classpathentry kind="src" path="frameworks/base/voip/java"/>
<classpathentry kind="src" path="frameworks/base/vpn/java"/>
<classpathentry kind="src" path="frameworks/base/wifi/java"/>
+ <classpathentry kind="src" path="frameworks/ex/common/java"/>
<classpathentry kind="src" path="development/samples/ApiDemos/src"/>
<classpathentry kind="src" path="development/samples/ApiDemos/tests/src"/>
<classpathentry kind="src" path="development/samples/Compass/src"/>
@@ -93,8 +95,6 @@
<classpathentry kind="src" path="external/apache-http/src"/>
<classpathentry kind="src" path="external/bouncycastle/src/main/java"/>
<classpathentry kind="src" path="external/nist-sip/java"/>
- <classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/google-common_intermediates/javalib.jar"/>
- <classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/gsf-client_intermediates/javalib.jar"/>
<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/guava_intermediates/javalib.jar"/>
<classpathentry kind="lib" path="packages/apps/Calculator/arity-2.1.2.jar"/>
<classpathentry kind="output" path="out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes"/>
diff --git a/ide/eclipse/README.importing-to-eclipse.txt b/ide/eclipse/README.importing-to-eclipse.txt
new file mode 100644
index 0000000..dffa0ab
--- /dev/null
+++ b/ide/eclipse/README.importing-to-eclipse.txt
@@ -0,0 +1,6 @@
+To import the formatter, go to the preferences, section Java > Code Style >
+formatter, then click on import and choose
+development/ide/eclipse/android-formatting.xml
+
+To import the import order, to go into Java > Code Style > Organize Import,
+then click on import and choose development/ide/eclipse/android.importorder
diff --git a/ide/eclipse/android-formatting.xml b/ide/eclipse/android-formatting.xml
index a64d4c6..9b43767 100644
--- a/ide/eclipse/android-formatting.xml
+++ b/ide/eclipse/android-formatting.xml
@@ -24,7 +24,7 @@
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
-<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
@@ -247,5 +247,6 @@
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
</profile>
</profiles>
diff --git a/ndk/platforms/android-3/arch-arm/lib/crtbegin_dynamic.o b/ndk/platforms/android-3/arch-arm/lib/crtbegin_dynamic.o
index 63d4efa..f34cba8 100644
--- a/ndk/platforms/android-3/arch-arm/lib/crtbegin_dynamic.o
+++ b/ndk/platforms/android-3/arch-arm/lib/crtbegin_dynamic.o
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/crtbegin_so.o b/ndk/platforms/android-3/arch-arm/lib/crtbegin_so.o
new file mode 100644
index 0000000..5230178
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/lib/crtbegin_so.o
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/crtbegin_static.o b/ndk/platforms/android-3/arch-arm/lib/crtbegin_static.o
index d11c79e..f34cba8 100644
--- a/ndk/platforms/android-3/arch-arm/lib/crtbegin_static.o
+++ b/ndk/platforms/android-3/arch-arm/lib/crtbegin_static.o
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/crtend_android.o b/ndk/platforms/android-3/arch-arm/lib/crtend_android.o
index 5b76af8..c57149e 100644
--- a/ndk/platforms/android-3/arch-arm/lib/crtend_android.o
+++ b/ndk/platforms/android-3/arch-arm/lib/crtend_android.o
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/crtend_so.o b/ndk/platforms/android-3/arch-arm/lib/crtend_so.o
new file mode 100644
index 0000000..c54db97
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/lib/crtend_so.o
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/libc.a b/ndk/platforms/android-3/arch-arm/lib/libc.a
index 4fdcafc..1877053 100644
--- a/ndk/platforms/android-3/arch-arm/lib/libc.a
+++ b/ndk/platforms/android-3/arch-arm/lib/libc.a
Binary files differ
diff --git a/ndk/platforms/android-3/include/jni.h b/ndk/platforms/android-3/include/jni.h
index ad954c8..495902c 100644
--- a/ndk/platforms/android-3/include/jni.h
+++ b/ndk/platforms/android-3/include/jni.h
@@ -1,13 +1,28 @@
/*
- * Copyright 2006 The Android Open Source Project
+ * Copyright (C) 2006 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.
+ */
+
+/*
* JNI specification, as defined by Sun:
* http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html
*
* Everything here is expected to be VM-neutral.
*/
-#ifndef _JNI_H
-#define _JNI_H
+
+#ifndef JNI_H_
+#define JNI_H_
#include <stdarg.h>
@@ -124,10 +139,10 @@
JNIWeakGlobalRefType = 3
} jobjectRefType;
-typedef struct {
- const char* name;
- const char* signature;
- void* fnPtr;
+typedef struct {
+ const char* name;
+ const char* signature;
+ void* fnPtr;
} JNINativeMethod;
struct _JNIEnv;
@@ -1037,7 +1052,7 @@
void* reserved0;
void* reserved1;
void* reserved2;
-
+
jint (*DestroyJavaVM)(JavaVM*);
jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
jint (*DetachCurrentThread)(JavaVM*);
@@ -1097,16 +1112,22 @@
*
* Note these are the only symbols exported for JNI by the VM.
*/
+#if 0 /* In practice, these are not exported by the NDK so don't declare them */
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
+#endif
+
+#define JNIIMPORT
+#define JNIEXPORT __attribute__ ((visibility ("default")))
+#define JNICALL
/*
* Prototypes for functions exported by loadable shared libs. These are
* called by JNI, not provided by JNI.
*/
-jint JNI_OnLoad(JavaVM* vm, void* reserved);
-void JNI_OnUnload(JavaVM* vm, void* reserved);
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved);
+JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved);
#ifdef __cplusplus
}
@@ -1132,9 +1153,4 @@
#define JNI_COMMIT 1 /* copy content, do not free buffer */
#define JNI_ABORT 2 /* free buffer w/o copying back */
-/* need these for Windows-aware headers */
-#define JNIIMPORT
-#define JNIEXPORT
-#define JNICALL
-
-#endif /*_JNI_H*/
+#endif /* JNI_H_ */
diff --git a/ndk/platforms/android-3/include/stdint.h b/ndk/platforms/android-3/include/stdint.h
index 237baa2..e791475 100644
--- a/ndk/platforms/android-3/include/stdint.h
+++ b/ndk/platforms/android-3/include/stdint.h
@@ -41,11 +41,6 @@
# define __STDINT_MACROS
#endif
-/* the definitions of STDINT_LIMITS depend on those of STDINT_MACROS */
-#if defined __STDINT_LIMITS && !defined __STDINT_MACROS
-# define __STDINT_MACROS
-#endif
-
#if !defined __STRICT_ANSI__ || __STDC_VERSION__ >= 199901L
# define __STDC_INT64__
#endif
@@ -185,13 +180,14 @@
# define UINT_FAST64_MAX UINT64_MAX
#endif
+#define __INT64_C(c) c ## LL
+#define __UINT64_C(c) c ## ULL
+
#ifdef __STDINT_MACROS
-# define __INT64_C(c) c ## LL
# define INT64_C(c) __INT64_C(c)
# define INT_LEAST64_C(c) INT64_C(c)
# define INT_FAST64_C(c) INT64_C(c)
-# define __UINT64_C(c) c ## ULL
# define UINT64_C(c) __UINT64_C(c)
# define UINT_LEAST64_C(c) UINT64_C(c)
# define UINT_FAST64_C(c) UINT64_C(c)
@@ -211,14 +207,20 @@
typedef int intptr_t;
typedef unsigned int uintptr_t;
+#ifdef __STDINT_LIMITS
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
+# define PTRDIFF_MIN INT32_MIN
+# define PTRDIFF_MAX INT32_MAX
+#endif
+
+#ifdef __STDINT_MACROS
# define INTPTR_C(c) INT32_C(c)
# define UINTPTR_C(c) UINT32_C(c)
# define PTRDIFF_C(c) INT32_C(c)
-# define PTRDIFF_MIN INT32_MIN
-# define PTRDIFF_MAX INT32_MAX
+#endif
+
/*
@@ -230,24 +232,32 @@
typedef uint64_t uintmax_t;
typedef int64_t intmax_t;
-#define INTMAX_MIN INT64_MIN
-#define INTMAX_MAX INT64_MAX
-#define UINTMAX_MAX UINT64_MAX
+#ifdef __STDINT_LIMITS
+# define INTMAX_MIN INT64_MIN
+# define INTMAX_MAX INT64_MAX
+# define UINTMAX_MAX UINT64_MAX
+#endif
-#define INTMAX_C(c) INT64_C(c)
-#define UINTMAX_C(c) UINT64_C(c)
+#ifdef __STDINT_MACROS
+# define INTMAX_C(c) INT64_C(c)
+# define UINTMAX_C(c) UINT64_C(c)
+#endif
#else /* !__STDC_INT64__ */
typedef uint32_t uintmax_t;
typedef int32_t intmax_t;
-#define INTMAX_MIN INT32_MIN
-#define INTMAX_MAX INT32_MAX
-#define UINTMAX_MAX UINT32_MAX
+#ifdef __STDINT_LIMITS
+# define INTMAX_MIN INT32_MIN
+# define INTMAX_MAX INT32_MAX
+# define UINTMAX_MAX UINT32_MAX
+#endif
-#define INTMAX_C(c) INT32_C(c)
-#define UINTMAX_C(c) UINT32_C(c)
+#ifdef __STDINT_MACROS
+# define INTMAX_C(c) INT32_C(c)
+# define UINTMAX_C(c) UINT32_C(c)
+#endif
#endif /* !__STDC_INT64__ */
diff --git a/ndk/platforms/android-3/include/unistd.h b/ndk/platforms/android-3/include/unistd.h
index 6d0515a..25fc334 100644
--- a/ndk/platforms/android-3/include/unistd.h
+++ b/ndk/platforms/android-3/include/unistd.h
@@ -126,7 +126,7 @@
extern ssize_t read(int, void *, size_t);
extern ssize_t write(int, const void *, size_t);
extern ssize_t pread(int, void *, size_t, off_t);
-extern ssize_t pwrite(int, void *, size_t, off_t);
+extern ssize_t pwrite(int, const void *, size_t, off_t);
extern int dup(int);
extern int dup2(int, int);
diff --git a/ndk/platforms/android-5/arch-x86/lib/crtbegin_dynamic.o b/ndk/platforms/android-5/arch-x86/lib/crtbegin_dynamic.o
deleted file mode 100644
index c620c30..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/crtbegin_dynamic.o
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/crtbegin_static.o b/ndk/platforms/android-5/arch-x86/lib/crtbegin_static.o
deleted file mode 100644
index c7505ee..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/crtbegin_static.o
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/crtend_android.o b/ndk/platforms/android-5/arch-x86/lib/crtend_android.o
deleted file mode 100644
index 2a835b7..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/crtend_android.o
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libc.a b/ndk/platforms/android-5/arch-x86/lib/libc.a
deleted file mode 100644
index 15403b1..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libc.a
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libc.so b/ndk/platforms/android-5/arch-x86/lib/libc.so
deleted file mode 100755
index fb6851c..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libc.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libc_common.a b/ndk/platforms/android-5/arch-x86/lib/libc_common.a
deleted file mode 100644
index aed18c7..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libc_common.a
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libdl.so b/ndk/platforms/android-5/arch-x86/lib/libdl.so
deleted file mode 100755
index 3f2cbeb..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libdl.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libm.a b/ndk/platforms/android-5/arch-x86/lib/libm.a
deleted file mode 100644
index 4e7c1f9..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libm.a
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libm.so b/ndk/platforms/android-5/arch-x86/lib/libm.so
deleted file mode 100755
index 1f46494..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libm.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libstdc++.a b/ndk/platforms/android-5/arch-x86/lib/libstdc++.a
deleted file mode 100644
index ff5c78e..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libstdc++.a
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libstdc++.so b/ndk/platforms/android-5/arch-x86/lib/libstdc++.so
deleted file mode 100755
index 79124d1..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libstdc++.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libthread_db.a b/ndk/platforms/android-5/arch-x86/lib/libthread_db.a
deleted file mode 100644
index abe0957..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libthread_db.a
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/lib/libthread_db.so b/ndk/platforms/android-5/arch-x86/lib/libthread_db.so
deleted file mode 100755
index 8614274..0000000
--- a/ndk/platforms/android-5/arch-x86/lib/libthread_db.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-8/include/unistd.h b/ndk/platforms/android-8/include/unistd.h
index d64c971..863d56d 100644
--- a/ndk/platforms/android-8/include/unistd.h
+++ b/ndk/platforms/android-8/include/unistd.h
@@ -130,7 +130,7 @@
extern ssize_t read(int, void *, size_t);
extern ssize_t write(int, const void *, size_t);
extern ssize_t pread(int, void *, size_t, off_t);
-extern ssize_t pwrite(int, void *, size_t, off_t);
+extern ssize_t pwrite(int, const void *, size_t, off_t);
extern int dup(int);
extern int dup2(int, int);
diff --git a/ndk/platforms/android-9/arch-arm/lib/libc.so b/ndk/platforms/android-9/arch-arm/lib/libc.so
new file mode 100644
index 0000000..5b3ba75
--- /dev/null
+++ b/ndk/platforms/android-9/arch-arm/lib/libc.so
Binary files differ
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/a.out.h b/ndk/platforms/android-9/arch-x86/include/asm/a.out.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/a.out.h
rename to ndk/platforms/android-9/arch-x86/include/asm/a.out.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/acpi.h b/ndk/platforms/android-9/arch-x86/include/asm/acpi.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/acpi.h
rename to ndk/platforms/android-9/arch-x86/include/asm/acpi.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/acpi_32.h b/ndk/platforms/android-9/arch-x86/include/asm/acpi_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/acpi_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/acpi_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/alternative.h b/ndk/platforms/android-9/arch-x86/include/asm/alternative.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/alternative.h
rename to ndk/platforms/android-9/arch-x86/include/asm/alternative.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/alternative_32.h b/ndk/platforms/android-9/arch-x86/include/asm/alternative_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/alternative_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/alternative_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/apic.h b/ndk/platforms/android-9/arch-x86/include/asm/apic.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/apic.h
rename to ndk/platforms/android-9/arch-x86/include/asm/apic.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/apic_32.h b/ndk/platforms/android-9/arch-x86/include/asm/apic_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/apic_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/apic_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/apicdef.h b/ndk/platforms/android-9/arch-x86/include/asm/apicdef.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/apicdef.h
rename to ndk/platforms/android-9/arch-x86/include/asm/apicdef.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/apicdef_32.h b/ndk/platforms/android-9/arch-x86/include/asm/apicdef_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/apicdef_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/apicdef_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/atomic.h b/ndk/platforms/android-9/arch-x86/include/asm/atomic.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/atomic.h
rename to ndk/platforms/android-9/arch-x86/include/asm/atomic.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/atomic_32.h b/ndk/platforms/android-9/arch-x86/include/asm/atomic_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/atomic_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/atomic_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/auxvec.h b/ndk/platforms/android-9/arch-x86/include/asm/auxvec.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/auxvec.h
rename to ndk/platforms/android-9/arch-x86/include/asm/auxvec.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/bitops.h b/ndk/platforms/android-9/arch-x86/include/asm/bitops.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/bitops.h
rename to ndk/platforms/android-9/arch-x86/include/asm/bitops.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/bitops_32.h b/ndk/platforms/android-9/arch-x86/include/asm/bitops_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/bitops_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/bitops_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/bug.h b/ndk/platforms/android-9/arch-x86/include/asm/bug.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/bug.h
rename to ndk/platforms/android-9/arch-x86/include/asm/bug.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/byteorder.h b/ndk/platforms/android-9/arch-x86/include/asm/byteorder.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/byteorder.h
rename to ndk/platforms/android-9/arch-x86/include/asm/byteorder.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/cache.h b/ndk/platforms/android-9/arch-x86/include/asm/cache.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/cache.h
rename to ndk/platforms/android-9/arch-x86/include/asm/cache.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/cacheflush.h b/ndk/platforms/android-9/arch-x86/include/asm/cacheflush.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/cacheflush.h
rename to ndk/platforms/android-9/arch-x86/include/asm/cacheflush.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/cmpxchg.h b/ndk/platforms/android-9/arch-x86/include/asm/cmpxchg.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/cmpxchg.h
rename to ndk/platforms/android-9/arch-x86/include/asm/cmpxchg.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/cmpxchg_32.h b/ndk/platforms/android-9/arch-x86/include/asm/cmpxchg_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/cmpxchg_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/cmpxchg_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/cpufeature.h b/ndk/platforms/android-9/arch-x86/include/asm/cpufeature.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/cpufeature.h
rename to ndk/platforms/android-9/arch-x86/include/asm/cpufeature.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/cpufeature_32.h b/ndk/platforms/android-9/arch-x86/include/asm/cpufeature_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/cpufeature_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/cpufeature_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/cputime.h b/ndk/platforms/android-9/arch-x86/include/asm/cputime.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/cputime.h
rename to ndk/platforms/android-9/arch-x86/include/asm/cputime.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/current.h b/ndk/platforms/android-9/arch-x86/include/asm/current.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/current.h
rename to ndk/platforms/android-9/arch-x86/include/asm/current.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/current_32.h b/ndk/platforms/android-9/arch-x86/include/asm/current_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/current_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/current_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/delay.h b/ndk/platforms/android-9/arch-x86/include/asm/delay.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/delay.h
rename to ndk/platforms/android-9/arch-x86/include/asm/delay.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/desc.h b/ndk/platforms/android-9/arch-x86/include/asm/desc.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/desc.h
rename to ndk/platforms/android-9/arch-x86/include/asm/desc.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/desc_32.h b/ndk/platforms/android-9/arch-x86/include/asm/desc_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/desc_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/desc_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/desc_defs.h b/ndk/platforms/android-9/arch-x86/include/asm/desc_defs.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/desc_defs.h
rename to ndk/platforms/android-9/arch-x86/include/asm/desc_defs.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/div64.h b/ndk/platforms/android-9/arch-x86/include/asm/div64.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/div64.h
rename to ndk/platforms/android-9/arch-x86/include/asm/div64.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/dma-mapping.h b/ndk/platforms/android-9/arch-x86/include/asm/dma-mapping.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/dma-mapping.h
rename to ndk/platforms/android-9/arch-x86/include/asm/dma-mapping.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/dma-mapping_32.h b/ndk/platforms/android-9/arch-x86/include/asm/dma-mapping_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/dma-mapping_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/dma-mapping_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/dma.h b/ndk/platforms/android-9/arch-x86/include/asm/dma.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/dma.h
rename to ndk/platforms/android-9/arch-x86/include/asm/dma.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/dma_32.h b/ndk/platforms/android-9/arch-x86/include/asm/dma_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/dma_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/dma_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/dwarf2.h b/ndk/platforms/android-9/arch-x86/include/asm/dwarf2.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/dwarf2.h
rename to ndk/platforms/android-9/arch-x86/include/asm/dwarf2.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/dwarf2_32.h b/ndk/platforms/android-9/arch-x86/include/asm/dwarf2_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/dwarf2_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/dwarf2_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/e820.h b/ndk/platforms/android-9/arch-x86/include/asm/e820.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/e820.h
rename to ndk/platforms/android-9/arch-x86/include/asm/e820.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/elf.h b/ndk/platforms/android-9/arch-x86/include/asm/elf.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/elf.h
rename to ndk/platforms/android-9/arch-x86/include/asm/elf.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/errno.h b/ndk/platforms/android-9/arch-x86/include/asm/errno.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/errno.h
rename to ndk/platforms/android-9/arch-x86/include/asm/errno.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/fcntl.h b/ndk/platforms/android-9/arch-x86/include/asm/fcntl.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/fcntl.h
rename to ndk/platforms/android-9/arch-x86/include/asm/fcntl.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/fixmap.h b/ndk/platforms/android-9/arch-x86/include/asm/fixmap.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/fixmap.h
rename to ndk/platforms/android-9/arch-x86/include/asm/fixmap.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/fixmap_32.h b/ndk/platforms/android-9/arch-x86/include/asm/fixmap_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/fixmap_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/fixmap_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/genapic.h b/ndk/platforms/android-9/arch-x86/include/asm/genapic.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/genapic.h
rename to ndk/platforms/android-9/arch-x86/include/asm/genapic.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/genapic_32.h b/ndk/platforms/android-9/arch-x86/include/asm/genapic_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/genapic_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/genapic_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/hardirq.h b/ndk/platforms/android-9/arch-x86/include/asm/hardirq.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/hardirq.h
rename to ndk/platforms/android-9/arch-x86/include/asm/hardirq.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/hardirq_32.h b/ndk/platforms/android-9/arch-x86/include/asm/hardirq_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/hardirq_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/hardirq_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/highmem.h b/ndk/platforms/android-9/arch-x86/include/asm/highmem.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/highmem.h
rename to ndk/platforms/android-9/arch-x86/include/asm/highmem.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/hw_irq.h b/ndk/platforms/android-9/arch-x86/include/asm/hw_irq.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/hw_irq.h
rename to ndk/platforms/android-9/arch-x86/include/asm/hw_irq.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/hw_irq_32.h b/ndk/platforms/android-9/arch-x86/include/asm/hw_irq_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/hw_irq_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/hw_irq_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/i387.h b/ndk/platforms/android-9/arch-x86/include/asm/i387.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/i387.h
rename to ndk/platforms/android-9/arch-x86/include/asm/i387.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/i387_32.h b/ndk/platforms/android-9/arch-x86/include/asm/i387_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/i387_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/i387_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/i8253.h b/ndk/platforms/android-9/arch-x86/include/asm/i8253.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/i8253.h
rename to ndk/platforms/android-9/arch-x86/include/asm/i8253.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/i8259.h b/ndk/platforms/android-9/arch-x86/include/asm/i8259.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/i8259.h
rename to ndk/platforms/android-9/arch-x86/include/asm/i8259.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ia32_unistd.h b/ndk/platforms/android-9/arch-x86/include/asm/ia32_unistd.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ia32_unistd.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ia32_unistd.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/io.h b/ndk/platforms/android-9/arch-x86/include/asm/io.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/io.h
rename to ndk/platforms/android-9/arch-x86/include/asm/io.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/io_32.h b/ndk/platforms/android-9/arch-x86/include/asm/io_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/io_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/io_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/io_apic.h b/ndk/platforms/android-9/arch-x86/include/asm/io_apic.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/io_apic.h
rename to ndk/platforms/android-9/arch-x86/include/asm/io_apic.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/io_apic_32.h b/ndk/platforms/android-9/arch-x86/include/asm/io_apic_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/io_apic_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/io_apic_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ioctl.h b/ndk/platforms/android-9/arch-x86/include/asm/ioctl.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ioctl.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ioctl.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ioctls.h b/ndk/platforms/android-9/arch-x86/include/asm/ioctls.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ioctls.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ioctls.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ipcbuf.h b/ndk/platforms/android-9/arch-x86/include/asm/ipcbuf.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ipcbuf.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ipcbuf.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/irq.h b/ndk/platforms/android-9/arch-x86/include/asm/irq.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/irq.h
rename to ndk/platforms/android-9/arch-x86/include/asm/irq.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/irq_32.h b/ndk/platforms/android-9/arch-x86/include/asm/irq_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/irq_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/irq_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/irqflags.h b/ndk/platforms/android-9/arch-x86/include/asm/irqflags.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/irqflags.h
rename to ndk/platforms/android-9/arch-x86/include/asm/irqflags.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/irqflags_32.h b/ndk/platforms/android-9/arch-x86/include/asm/irqflags_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/irqflags_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/irqflags_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ist.h b/ndk/platforms/android-9/arch-x86/include/asm/ist.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ist.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ist.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/kmap_types.h b/ndk/platforms/android-9/arch-x86/include/asm/kmap_types.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/kmap_types.h
rename to ndk/platforms/android-9/arch-x86/include/asm/kmap_types.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ldt.h b/ndk/platforms/android-9/arch-x86/include/asm/ldt.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ldt.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ldt.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/linkage.h b/ndk/platforms/android-9/arch-x86/include/asm/linkage.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/linkage.h
rename to ndk/platforms/android-9/arch-x86/include/asm/linkage.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/linkage_32.h b/ndk/platforms/android-9/arch-x86/include/asm/linkage_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/linkage_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/linkage_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/local.h b/ndk/platforms/android-9/arch-x86/include/asm/local.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/local.h
rename to ndk/platforms/android-9/arch-x86/include/asm/local.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/local_32.h b/ndk/platforms/android-9/arch-x86/include/asm/local_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/local_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/local_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/math_emu.h b/ndk/platforms/android-9/arch-x86/include/asm/math_emu.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/math_emu.h
rename to ndk/platforms/android-9/arch-x86/include/asm/math_emu.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mc146818rtc.h b/ndk/platforms/android-9/arch-x86/include/asm/mc146818rtc.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mc146818rtc.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mc146818rtc.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mc146818rtc_32.h b/ndk/platforms/android-9/arch-x86/include/asm/mc146818rtc_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mc146818rtc_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mc146818rtc_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mman.h b/ndk/platforms/android-9/arch-x86/include/asm/mman.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mman.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mman.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mmsegment.h b/ndk/platforms/android-9/arch-x86/include/asm/mmsegment.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mmsegment.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mmsegment.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mmu.h b/ndk/platforms/android-9/arch-x86/include/asm/mmu.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mmu.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mmu.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/module.h b/ndk/platforms/android-9/arch-x86/include/asm/module.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/module.h
rename to ndk/platforms/android-9/arch-x86/include/asm/module.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/module_32.h b/ndk/platforms/android-9/arch-x86/include/asm/module_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/module_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/module_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mpspec.h b/ndk/platforms/android-9/arch-x86/include/asm/mpspec.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mpspec.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mpspec.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mpspec_32.h b/ndk/platforms/android-9/arch-x86/include/asm/mpspec_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mpspec_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mpspec_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/mpspec_def.h b/ndk/platforms/android-9/arch-x86/include/asm/mpspec_def.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/mpspec_def.h
rename to ndk/platforms/android-9/arch-x86/include/asm/mpspec_def.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/msgbuf.h b/ndk/platforms/android-9/arch-x86/include/asm/msgbuf.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/msgbuf.h
rename to ndk/platforms/android-9/arch-x86/include/asm/msgbuf.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/msr-index.h b/ndk/platforms/android-9/arch-x86/include/asm/msr-index.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/msr-index.h
rename to ndk/platforms/android-9/arch-x86/include/asm/msr-index.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/msr.h b/ndk/platforms/android-9/arch-x86/include/asm/msr.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/msr.h
rename to ndk/platforms/android-9/arch-x86/include/asm/msr.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/page.h b/ndk/platforms/android-9/arch-x86/include/asm/page.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/page.h
rename to ndk/platforms/android-9/arch-x86/include/asm/page.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/page_32.h b/ndk/platforms/android-9/arch-x86/include/asm/page_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/page_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/page_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/param.h b/ndk/platforms/android-9/arch-x86/include/asm/param.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/param.h
rename to ndk/platforms/android-9/arch-x86/include/asm/param.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/paravirt.h b/ndk/platforms/android-9/arch-x86/include/asm/paravirt.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/paravirt.h
rename to ndk/platforms/android-9/arch-x86/include/asm/paravirt.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/pda.h b/ndk/platforms/android-9/arch-x86/include/asm/pda.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/pda.h
rename to ndk/platforms/android-9/arch-x86/include/asm/pda.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/percpu.h b/ndk/platforms/android-9/arch-x86/include/asm/percpu.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/percpu.h
rename to ndk/platforms/android-9/arch-x86/include/asm/percpu.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/percpu_32.h b/ndk/platforms/android-9/arch-x86/include/asm/percpu_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/percpu_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/percpu_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/pgalloc.h b/ndk/platforms/android-9/arch-x86/include/asm/pgalloc.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/pgalloc.h
rename to ndk/platforms/android-9/arch-x86/include/asm/pgalloc.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/pgalloc_32.h b/ndk/platforms/android-9/arch-x86/include/asm/pgalloc_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/pgalloc_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/pgalloc_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/pgtable-2level-defs.h b/ndk/platforms/android-9/arch-x86/include/asm/pgtable-2level-defs.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/pgtable-2level-defs.h
rename to ndk/platforms/android-9/arch-x86/include/asm/pgtable-2level-defs.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/pgtable-2level.h b/ndk/platforms/android-9/arch-x86/include/asm/pgtable-2level.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/pgtable-2level.h
rename to ndk/platforms/android-9/arch-x86/include/asm/pgtable-2level.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/pgtable.h b/ndk/platforms/android-9/arch-x86/include/asm/pgtable.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/pgtable.h
rename to ndk/platforms/android-9/arch-x86/include/asm/pgtable.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/pgtable_32.h b/ndk/platforms/android-9/arch-x86/include/asm/pgtable_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/pgtable_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/pgtable_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/poll.h b/ndk/platforms/android-9/arch-x86/include/asm/poll.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/poll.h
rename to ndk/platforms/android-9/arch-x86/include/asm/poll.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/posix_types.h b/ndk/platforms/android-9/arch-x86/include/asm/posix_types.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/posix_types.h
rename to ndk/platforms/android-9/arch-x86/include/asm/posix_types.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/posix_types_32.h b/ndk/platforms/android-9/arch-x86/include/asm/posix_types_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/posix_types_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/posix_types_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/prctl.h b/ndk/platforms/android-9/arch-x86/include/asm/prctl.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/prctl.h
rename to ndk/platforms/android-9/arch-x86/include/asm/prctl.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/processor-flags.h b/ndk/platforms/android-9/arch-x86/include/asm/processor-flags.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/processor-flags.h
rename to ndk/platforms/android-9/arch-x86/include/asm/processor-flags.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/processor.h b/ndk/platforms/android-9/arch-x86/include/asm/processor.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/processor.h
rename to ndk/platforms/android-9/arch-x86/include/asm/processor.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/processor_32.h b/ndk/platforms/android-9/arch-x86/include/asm/processor_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/processor_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/processor_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ptrace-abi.h b/ndk/platforms/android-9/arch-x86/include/asm/ptrace-abi.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ptrace-abi.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ptrace-abi.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/ptrace.h b/ndk/platforms/android-9/arch-x86/include/asm/ptrace.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/ptrace.h
rename to ndk/platforms/android-9/arch-x86/include/asm/ptrace.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/required-features.h b/ndk/platforms/android-9/arch-x86/include/asm/required-features.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/required-features.h
rename to ndk/platforms/android-9/arch-x86/include/asm/required-features.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/resource.h b/ndk/platforms/android-9/arch-x86/include/asm/resource.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/resource.h
rename to ndk/platforms/android-9/arch-x86/include/asm/resource.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/rwlock.h b/ndk/platforms/android-9/arch-x86/include/asm/rwlock.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/rwlock.h
rename to ndk/platforms/android-9/arch-x86/include/asm/rwlock.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/scatterlist.h b/ndk/platforms/android-9/arch-x86/include/asm/scatterlist.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/scatterlist.h
rename to ndk/platforms/android-9/arch-x86/include/asm/scatterlist.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/scatterlist_32.h b/ndk/platforms/android-9/arch-x86/include/asm/scatterlist_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/scatterlist_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/scatterlist_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/sections.h b/ndk/platforms/android-9/arch-x86/include/asm/sections.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/sections.h
rename to ndk/platforms/android-9/arch-x86/include/asm/sections.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/segment.h b/ndk/platforms/android-9/arch-x86/include/asm/segment.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/segment.h
rename to ndk/platforms/android-9/arch-x86/include/asm/segment.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/segment_32.h b/ndk/platforms/android-9/arch-x86/include/asm/segment_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/segment_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/segment_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/semaphore.h b/ndk/platforms/android-9/arch-x86/include/asm/semaphore.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/semaphore.h
rename to ndk/platforms/android-9/arch-x86/include/asm/semaphore.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/semaphore_32.h b/ndk/platforms/android-9/arch-x86/include/asm/semaphore_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/semaphore_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/semaphore_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/sembuf.h b/ndk/platforms/android-9/arch-x86/include/asm/sembuf.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/sembuf.h
rename to ndk/platforms/android-9/arch-x86/include/asm/sembuf.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/setup.h b/ndk/platforms/android-9/arch-x86/include/asm/setup.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/setup.h
rename to ndk/platforms/android-9/arch-x86/include/asm/setup.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/shmbuf.h b/ndk/platforms/android-9/arch-x86/include/asm/shmbuf.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/shmbuf.h
rename to ndk/platforms/android-9/arch-x86/include/asm/shmbuf.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/shmparam.h b/ndk/platforms/android-9/arch-x86/include/asm/shmparam.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/shmparam.h
rename to ndk/platforms/android-9/arch-x86/include/asm/shmparam.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/sigcontext.h b/ndk/platforms/android-9/arch-x86/include/asm/sigcontext.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/sigcontext.h
rename to ndk/platforms/android-9/arch-x86/include/asm/sigcontext.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/siginfo.h b/ndk/platforms/android-9/arch-x86/include/asm/siginfo.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/siginfo.h
rename to ndk/platforms/android-9/arch-x86/include/asm/siginfo.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/signal.h b/ndk/platforms/android-9/arch-x86/include/asm/signal.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/signal.h
rename to ndk/platforms/android-9/arch-x86/include/asm/signal.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/smp.h b/ndk/platforms/android-9/arch-x86/include/asm/smp.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/smp.h
rename to ndk/platforms/android-9/arch-x86/include/asm/smp.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/smp_32.h b/ndk/platforms/android-9/arch-x86/include/asm/smp_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/smp_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/smp_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/socket.h b/ndk/platforms/android-9/arch-x86/include/asm/socket.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/socket.h
rename to ndk/platforms/android-9/arch-x86/include/asm/socket.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/sockios.h b/ndk/platforms/android-9/arch-x86/include/asm/sockios.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/sockios.h
rename to ndk/platforms/android-9/arch-x86/include/asm/sockios.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/spinlock.h b/ndk/platforms/android-9/arch-x86/include/asm/spinlock.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/spinlock.h
rename to ndk/platforms/android-9/arch-x86/include/asm/spinlock.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/spinlock_32.h b/ndk/platforms/android-9/arch-x86/include/asm/spinlock_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/spinlock_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/spinlock_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/spinlock_types.h b/ndk/platforms/android-9/arch-x86/include/asm/spinlock_types.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/spinlock_types.h
rename to ndk/platforms/android-9/arch-x86/include/asm/spinlock_types.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/stat.h b/ndk/platforms/android-9/arch-x86/include/asm/stat.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/stat.h
rename to ndk/platforms/android-9/arch-x86/include/asm/stat.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/statfs.h b/ndk/platforms/android-9/arch-x86/include/asm/statfs.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/statfs.h
rename to ndk/platforms/android-9/arch-x86/include/asm/statfs.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/string.h b/ndk/platforms/android-9/arch-x86/include/asm/string.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/string.h
rename to ndk/platforms/android-9/arch-x86/include/asm/string.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/string_32.h b/ndk/platforms/android-9/arch-x86/include/asm/string_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/string_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/string_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/swiotlb.h b/ndk/platforms/android-9/arch-x86/include/asm/swiotlb.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/swiotlb.h
rename to ndk/platforms/android-9/arch-x86/include/asm/swiotlb.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/system.h b/ndk/platforms/android-9/arch-x86/include/asm/system.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/system.h
rename to ndk/platforms/android-9/arch-x86/include/asm/system.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/system_32.h b/ndk/platforms/android-9/arch-x86/include/asm/system_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/system_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/system_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/termbits.h b/ndk/platforms/android-9/arch-x86/include/asm/termbits.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/termbits.h
rename to ndk/platforms/android-9/arch-x86/include/asm/termbits.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/termios.h b/ndk/platforms/android-9/arch-x86/include/asm/termios.h
similarity index 90%
rename from ndk/platforms/android-5/arch-x86/include/asm/termios.h
rename to ndk/platforms/android-9/arch-x86/include/asm/termios.h
index 01bdca4..6542c78 100644
--- a/ndk/platforms/android-5/arch-x86/include/asm/termios.h
+++ b/ndk/platforms/android-9/arch-x86/include/asm/termios.h
@@ -53,15 +53,15 @@
#define N_PPP 3
#define N_STRIP 4
#define N_AX25 5
-#define N_X25 6
+#define N_X25 6
#define N_6PACK 7
-#define N_MASC 8
-#define N_R3964 9
-#define N_PROFIBUS_FDL 10
-#define N_IRDA 11
-#define N_SMSBLOCK 12
-#define N_HDLC 13
+#define N_MASC 8
+#define N_R3964 9
+#define N_PROFIBUS_FDL 10
+#define N_IRDA 11
+#define N_SMSBLOCK 12
+#define N_HDLC 13
#define N_SYNC_PPP 14
-#define N_HCI 15
+#define N_HCI 15
#endif
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/thread_info.h b/ndk/platforms/android-9/arch-x86/include/asm/thread_info.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/thread_info.h
rename to ndk/platforms/android-9/arch-x86/include/asm/thread_info.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/thread_info_32.h b/ndk/platforms/android-9/arch-x86/include/asm/thread_info_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/thread_info_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/thread_info_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/tlbflush.h b/ndk/platforms/android-9/arch-x86/include/asm/tlbflush.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/tlbflush.h
rename to ndk/platforms/android-9/arch-x86/include/asm/tlbflush.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/tlbflush_32.h b/ndk/platforms/android-9/arch-x86/include/asm/tlbflush_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/tlbflush_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/tlbflush_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/tsc.h b/ndk/platforms/android-9/arch-x86/include/asm/tsc.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/tsc.h
rename to ndk/platforms/android-9/arch-x86/include/asm/tsc.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/types.h b/ndk/platforms/android-9/arch-x86/include/asm/types.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/types.h
rename to ndk/platforms/android-9/arch-x86/include/asm/types.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/uaccess.h b/ndk/platforms/android-9/arch-x86/include/asm/uaccess.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/uaccess.h
rename to ndk/platforms/android-9/arch-x86/include/asm/uaccess.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/uaccess_32.h b/ndk/platforms/android-9/arch-x86/include/asm/uaccess_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/uaccess_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/uaccess_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/unaligned.h b/ndk/platforms/android-9/arch-x86/include/asm/unaligned.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/unaligned.h
rename to ndk/platforms/android-9/arch-x86/include/asm/unaligned.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/unistd.h b/ndk/platforms/android-9/arch-x86/include/asm/unistd.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/unistd.h
rename to ndk/platforms/android-9/arch-x86/include/asm/unistd.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/unistd_32.h b/ndk/platforms/android-9/arch-x86/include/asm/unistd_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/unistd_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/unistd_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/user.h b/ndk/platforms/android-9/arch-x86/include/asm/user.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/user.h
rename to ndk/platforms/android-9/arch-x86/include/asm/user.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/user32.h b/ndk/platforms/android-9/arch-x86/include/asm/user32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/user32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/user32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/user_32.h b/ndk/platforms/android-9/arch-x86/include/asm/user_32.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/user_32.h
rename to ndk/platforms/android-9/arch-x86/include/asm/user_32.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/vm86.h b/ndk/platforms/android-9/arch-x86/include/asm/vm86.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/vm86.h
rename to ndk/platforms/android-9/arch-x86/include/asm/vm86.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/voyager.h b/ndk/platforms/android-9/arch-x86/include/asm/voyager.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/voyager.h
rename to ndk/platforms/android-9/arch-x86/include/asm/voyager.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/vsyscall.h b/ndk/platforms/android-9/arch-x86/include/asm/vsyscall.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/vsyscall.h
rename to ndk/platforms/android-9/arch-x86/include/asm/vsyscall.h
diff --git a/ndk/platforms/android-5/arch-x86/include/asm/xen/hypercall.h b/ndk/platforms/android-9/arch-x86/include/asm/xen/hypercall.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/asm/xen/hypercall.h
rename to ndk/platforms/android-9/arch-x86/include/asm/xen/hypercall.h
diff --git a/ndk/platforms/android-5/arch-x86/include/endian.h b/ndk/platforms/android-9/arch-x86/include/endian.h
similarity index 89%
rename from ndk/platforms/android-5/arch-x86/include/endian.h
rename to ndk/platforms/android-9/arch-x86/include/endian.h
index ad37919..4a70536 100644
--- a/ndk/platforms/android-5/arch-x86/include/endian.h
+++ b/ndk/platforms/android-9/arch-x86/include/endian.h
@@ -31,14 +31,14 @@
#if defined(_KERNEL) && !defined(I386_CPU)
#define __swap32md(x) ({ \
- u_int32_t __swap32md_x = (x); \
+ uint32_t __swap32md_x = (x); \
\
__asm ("bswap %1" : "+r" (__swap32md_x)); \
__swap32md_x; \
})
#else
#define __swap32md(x) ({ \
- u_int32_t __swap32md_x = (x); \
+ uint32_t __swap32md_x = (x); \
\
__asm ("rorw $8, %w1; rorl $16, %1; rorw $8, %w1" : \
"+r" (__swap32md_x)); \
@@ -47,13 +47,13 @@
#endif /* _KERNEL && !I386_CPU */
#define __swap64md(x) ({ \
- u_int64_t __swap64md_x = (x); \
+ uint64_t __swap64md_x = (x); \
\
- (u_int64_t)__swap32md(__swap64md_x >> 32) | \
- (u_int64_t)__swap32md(__swap64md_x & 0xffffffff) << 32; \
+ (uint64_t)__swap32md(__swap64md_x >> 32) | \
+ (uint64_t)__swap32md(__swap64md_x & 0xffffffff) << 32; \
})
#define __swap16md(x) ({ \
- u_int16_t __swap16md_x = (x); \
+ uint16_t __swap16md_x = (x); \
\
__asm ("rorw $8, %w1" : "+r" (__swap16md_x)); \
__swap16md_x; \
diff --git a/ndk/platforms/android-5/arch-x86/include/fenv.h b/ndk/platforms/android-9/arch-x86/include/fenv.h
similarity index 97%
rename from ndk/platforms/android-5/arch-x86/include/fenv.h
rename to ndk/platforms/android-9/arch-x86/include/fenv.h
index b124366..5fe64e2 100644
--- a/ndk/platforms/android-5/arch-x86/include/fenv.h
+++ b/ndk/platforms/android-9/arch-x86/include/fenv.h
@@ -102,7 +102,7 @@
#define __fnclex() __asm __volatile("fnclex")
#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env)))
#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
-#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
+#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=a" (*(__sw)))
#define __fwait() __asm __volatile("fwait")
#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
@@ -131,7 +131,8 @@
static __inline int
fegetexceptflag(fexcept_t *__flagp, int __excepts)
{
- int __mxcsr, __status;
+ int __mxcsr;
+ short __status;
__fnstsw(&__status);
if (__HAS_SSE())
@@ -148,7 +149,8 @@
static __inline int
fetestexcept(int __excepts)
{
- int __mxcsr, __status;
+ int __mxcsr;
+ short __status;
__fnstsw(&__status);
if (__HAS_SSE())
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/_types.h b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
similarity index 95%
rename from ndk/platforms/android-5/arch-x86/include/machine/_types.h
rename to ndk/platforms/android-9/arch-x86/include/machine/_types.h
index be4f6e4..65892a1 100644
--- a/ndk/platforms/android-5/arch-x86/include/machine/_types.h
+++ b/ndk/platforms/android-9/arch-x86/include/machine/_types.h
@@ -36,9 +36,9 @@
#define _I386__TYPES_H_
/* the kernel defines size_t as unsigned int, but g++ wants it to be unsigned long */
-#ifndef _SIZE_T
-# define _SIZE_T
-# ifdef ANDROID
+#ifndef _SIZE_T_DEFINED_
+# define _SIZE_T_DEFINED_
+# ifdef __ANDROID__
typedef unsigned int size_t;
# else
typedef unsigned long size_t;
@@ -51,12 +51,13 @@
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
-typedef long ptrdiff_t;
+# ifdef __ANDROID__
+ typedef int ptrdiff_t;
+# else
+ typedef long ptrdiff_t;
+# endif
#endif
-#define _OFF_T_DEFINED_
-#define _SIZE_T_DEFINED_
-
#include <linux/types.h>
/* 7.18.1.1 Exact-width integer types */
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/asm.h b/ndk/platforms/android-9/arch-x86/include/machine/asm.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/asm.h
rename to ndk/platforms/android-9/arch-x86/include/machine/asm.h
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/cdefs.h b/ndk/platforms/android-9/arch-x86/include/machine/cdefs.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/cdefs.h
rename to ndk/platforms/android-9/arch-x86/include/machine/cdefs.h
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/exec.h b/ndk/platforms/android-9/arch-x86/include/machine/exec.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/exec.h
rename to ndk/platforms/android-9/arch-x86/include/machine/exec.h
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/ieee.h b/ndk/platforms/android-9/arch-x86/include/machine/ieee.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/ieee.h
rename to ndk/platforms/android-9/arch-x86/include/machine/ieee.h
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/internal_types.h b/ndk/platforms/android-9/arch-x86/include/machine/internal_types.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/internal_types.h
rename to ndk/platforms/android-9/arch-x86/include/machine/internal_types.h
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/kernel.h b/ndk/platforms/android-9/arch-x86/include/machine/kernel.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/kernel.h
rename to ndk/platforms/android-9/arch-x86/include/machine/kernel.h
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/limits.h b/ndk/platforms/android-9/arch-x86/include/machine/limits.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/limits.h
rename to ndk/platforms/android-9/arch-x86/include/machine/limits.h
diff --git a/ndk/platforms/android-5/arch-x86/include/machine/setjmp.h b/ndk/platforms/android-9/arch-x86/include/machine/setjmp.h
similarity index 100%
rename from ndk/platforms/android-5/arch-x86/include/machine/setjmp.h
rename to ndk/platforms/android-9/arch-x86/include/machine/setjmp.h
diff --git a/ndk/platforms/android-9/arch-x86/include/sys/atomics.h b/ndk/platforms/android-9/arch-x86/include/sys/atomics.h
new file mode 100644
index 0000000..7aed3ae
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/include/sys/atomics.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _SYS_ATOMICS_H
+#define _SYS_ATOMICS_H
+
+#include <sys/cdefs.h>
+#include <sys/time.h>
+
+__BEGIN_DECLS
+
+static inline __attribute__((always_inline)) int
+__atomic_cmpxchg(int old, int _new, volatile int *ptr)
+{
+ return !__sync_bool_compare_and_swap (ptr, old, _new);
+}
+
+static inline __attribute__((always_inline)) int
+__atomic_swap(int _new, volatile int *ptr)
+{
+ return __sync_lock_test_and_set(ptr, _new);
+}
+
+static inline __attribute__((always_inline)) int
+__atomic_dec(volatile int *ptr)
+{
+ return __sync_fetch_and_sub (ptr, 1);
+}
+
+static inline __attribute__((always_inline)) int
+__atomic_inc(volatile int *ptr)
+{
+ return __sync_fetch_and_add (ptr, 1);
+}
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
+int __futex_wake(volatile void *ftx, int count);
+
+__END_DECLS
+
+#endif /* _SYS_ATOMICS_H */
diff --git a/ndk/platforms/android-9/arch-x86/lib/crtbegin_dynamic.o b/ndk/platforms/android-9/arch-x86/lib/crtbegin_dynamic.o
new file mode 100644
index 0000000..17704f5
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/crtbegin_dynamic.o
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/crtbegin_so.o b/ndk/platforms/android-9/arch-x86/lib/crtbegin_so.o
new file mode 100644
index 0000000..cf50f1d
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/crtbegin_so.o
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/crtbegin_static.o b/ndk/platforms/android-9/arch-x86/lib/crtbegin_static.o
new file mode 100644
index 0000000..17704f5
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/crtbegin_static.o
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/crtend_android.o b/ndk/platforms/android-9/arch-x86/lib/crtend_android.o
new file mode 100644
index 0000000..87716a0
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/crtend_android.o
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/crtend_so.o b/ndk/platforms/android-9/arch-x86/lib/crtend_so.o
new file mode 100644
index 0000000..4c4460f
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/crtend_so.o
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libEGL.so b/ndk/platforms/android-9/arch-x86/lib/libEGL.so
new file mode 100755
index 0000000..49020a9
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libEGL.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libGLESv1_CM.so b/ndk/platforms/android-9/arch-x86/lib/libGLESv1_CM.so
new file mode 100755
index 0000000..83ddd59
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libGLESv1_CM.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libGLESv2.so b/ndk/platforms/android-9/arch-x86/lib/libGLESv2.so
new file mode 100755
index 0000000..7c72567
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libGLESv2.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libOpenSLES.so b/ndk/platforms/android-9/arch-x86/lib/libOpenSLES.so
new file mode 100755
index 0000000..de81e57
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libOpenSLES.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libandroid.so b/ndk/platforms/android-9/arch-x86/lib/libandroid.so
new file mode 100755
index 0000000..419d414
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libandroid.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libc.a b/ndk/platforms/android-9/arch-x86/lib/libc.a
new file mode 100644
index 0000000..90220b0
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libc.a
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libc.so b/ndk/platforms/android-9/arch-x86/lib/libc.so
new file mode 100755
index 0000000..fd6c188
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libc.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libdl.so b/ndk/platforms/android-9/arch-x86/lib/libdl.so
new file mode 100755
index 0000000..c31fd46
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libdl.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libjnigraphics.so b/ndk/platforms/android-9/arch-x86/lib/libjnigraphics.so
new file mode 100755
index 0000000..2a0494f
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libjnigraphics.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/liblog.so b/ndk/platforms/android-9/arch-x86/lib/liblog.so
new file mode 100755
index 0000000..6ab1fd2
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/liblog.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libm.a b/ndk/platforms/android-9/arch-x86/lib/libm.a
new file mode 100644
index 0000000..34f3c1f
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libm.a
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libm.so b/ndk/platforms/android-9/arch-x86/lib/libm.so
new file mode 100755
index 0000000..78c3def
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libm.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libstdc++.a b/ndk/platforms/android-9/arch-x86/lib/libstdc++.a
new file mode 100644
index 0000000..336bcfa
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libstdc++.a
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libstdc++.so b/ndk/platforms/android-9/arch-x86/lib/libstdc++.so
new file mode 100755
index 0000000..248dc48
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libstdc++.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libthread_db.a b/ndk/platforms/android-9/arch-x86/lib/libthread_db.a
new file mode 100644
index 0000000..9525ff1
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libthread_db.a
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libz.a b/ndk/platforms/android-9/arch-x86/lib/libz.a
new file mode 100644
index 0000000..5c91867
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libz.a
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libz.so b/ndk/platforms/android-9/arch-x86/lib/libz.so
new file mode 100755
index 0000000..384e8c4
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/lib/libz.so
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.txt
new file mode 100644
index 0000000..8550335
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.txt
@@ -0,0 +1,41 @@
+eglBindAPI
+eglBindTexImage
+eglChooseConfig
+eglCopyBuffers
+eglCreateContext
+eglCreateImageKHR
+eglCreatePbufferFromClientBuffer
+eglCreatePbufferSurface
+eglCreatePixmapSurface
+eglCreateWindowSurface
+eglDestroyContext
+eglDestroyImageKHR
+eglDestroySurface
+eglGetConfigAttrib
+eglGetConfigs
+eglGetCurrentContext
+eglGetCurrentDisplay
+eglGetCurrentSurface
+eglGetDisplay
+eglGetError
+eglGetProcAddress
+eglInitialize
+eglLockSurfaceKHR
+eglMakeCurrent
+eglQueryAPI
+eglQueryContext
+eglQueryString
+eglQuerySurface
+eglReleaseTexImage
+eglReleaseThread
+eglSetSwapRectangleANDROID
+eglSurfaceAttrib
+eglSwapBuffers
+eglSwapInterval
+eglTerminate
+eglUnlockSurfaceKHR
+eglWaitClient
+eglWaitGL
+eglWaitNative
+__FINI_ARRAY__
+__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt
new file mode 100644
index 0000000..7c53cfa
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt
@@ -0,0 +1,280 @@
+glActiveTexture
+glAlphaFunc
+glAlphaFuncx
+glAlphaFuncxOES
+glBindBuffer
+glBindFramebufferOES
+glBindRenderbufferOES
+glBindTexture
+glBindVertexArrayOES
+glBlendEquationOES
+glBlendEquationSeparateOES
+glBlendFunc
+glBlendFuncSeparateOES
+glBufferData
+glBufferSubData
+glCheckFramebufferStatusOES
+glClear
+glClearColor
+glClearColorx
+glClearColorxOES
+glClearDepthf
+glClearDepthfOES
+glClearDepthx
+glClearDepthxOES
+glClearStencil
+glClientActiveTexture
+glClipPlanef
+glClipPlanefIMG
+glClipPlanefOES
+glClipPlanex
+glClipPlanexIMG
+glClipPlanexOES
+glColor4f
+glColor4ub
+glColor4x
+glColor4xOES
+glColorMask
+glColorPointer
+glColorPointerBounds
+glCompressedTexImage2D
+glCompressedTexSubImage2D
+glCopyTexImage2D
+glCopyTexSubImage2D
+glCullFace
+glCurrentPaletteMatrixOES
+glDeleteBuffers
+glDeleteFencesNV
+glDeleteFramebuffersOES
+glDeleteRenderbuffersOES
+glDeleteTextures
+glDeleteVertexArraysOES
+glDepthFunc
+glDepthMask
+glDepthRangef
+glDepthRangefOES
+glDepthRangex
+glDepthRangexOES
+glDisable
+glDisableClientState
+glDisableDriverControlQCOM
+glDiscardFramebufferEXT
+glDrawArrays
+glDrawElements
+glDrawTexfOES
+glDrawTexfvOES
+glDrawTexiOES
+glDrawTexivOES
+glDrawTexsOES
+glDrawTexsvOES
+glDrawTexxOES
+glDrawTexxvOES
+glEGLImageTargetRenderbufferStorageOES
+glEGLImageTargetTexture2DOES
+glEnable
+glEnableClientState
+glEnableDriverControlQCOM
+glEndTilingQCOM
+glExtGetBufferPointervQCOM
+glExtGetBuffersQCOM
+glExtGetFramebuffersQCOM
+glExtGetProgramBinarySourceQCOM
+glExtGetProgramsQCOM
+glExtGetRenderbuffersQCOM
+glExtGetShadersQCOM
+glExtGetTexLevelParameterivQCOM
+glExtGetTexSubImageQCOM
+glExtGetTexturesQCOM
+glExtIsProgramBinaryQCOM
+glExtTexObjectStateOverrideiQCOM
+glFinish
+glFinishFenceNV
+glFlush
+glFogf
+glFogfv
+glFogx
+glFogxOES
+glFogxv
+glFogxvOES
+glFramebufferRenderbufferOES
+glFramebufferTexture2DMultisampleIMG
+glFramebufferTexture2DOES
+glFrontFace
+glFrustumf
+glFrustumfOES
+glFrustumx
+glFrustumxOES
+glGenBuffers
+glGenFencesNV
+glGenFramebuffersOES
+glGenRenderbuffersOES
+glGenTextures
+glGenVertexArraysOES
+glGenerateMipmapOES
+glGetBooleanv
+glGetBufferParameteriv
+glGetBufferPointervOES
+glGetClipPlanef
+glGetClipPlanefOES
+glGetClipPlanex
+glGetClipPlanexOES
+glGetDriverControlStringQCOM
+glGetDriverControlsQCOM
+glGetError
+glGetFenceivNV
+glGetFixedv
+glGetFixedvOES
+glGetFloatv
+glGetFramebufferAttachmentParameterivOES
+glGetIntegerv
+glGetLightfv
+glGetLightxv
+glGetLightxvOES
+glGetMaterialfv
+glGetMaterialxv
+glGetMaterialxvOES
+glGetPointerv
+glGetRenderbufferParameterivOES
+glGetString
+glGetTexEnvfv
+glGetTexEnviv
+glGetTexEnvxv
+glGetTexEnvxvOES
+glGetTexGenfvOES
+glGetTexGenivOES
+glGetTexGenxvOES
+glGetTexParameterfv
+glGetTexParameteriv
+glGetTexParameterxv
+glGetTexParameterxvOES
+glHint
+glIsBuffer
+glIsEnabled
+glIsFenceNV
+glIsFramebufferOES
+glIsRenderbufferOES
+glIsTexture
+glIsVertexArrayOES
+glLightModelf
+glLightModelfv
+glLightModelx
+glLightModelxOES
+glLightModelxv
+glLightModelxvOES
+glLightf
+glLightfv
+glLightx
+glLightxOES
+glLightxv
+glLightxvOES
+glLineWidth
+glLineWidthx
+glLineWidthxOES
+glLoadIdentity
+glLoadMatrixf
+glLoadMatrixx
+glLoadMatrixxOES
+glLoadPaletteFromModelViewMatrixOES
+glLogicOp
+glMapBufferOES
+glMaterialf
+glMaterialfv
+glMaterialx
+glMaterialxOES
+glMaterialxv
+glMaterialxvOES
+glMatrixIndexPointerOES
+glMatrixIndexPointerOESBounds
+glMatrixMode
+glMultMatrixf
+glMultMatrixx
+glMultMatrixxOES
+glMultiDrawArraysEXT
+glMultiDrawElementsEXT
+glMultiTexCoord4f
+glMultiTexCoord4x
+glMultiTexCoord4xOES
+glNormal3f
+glNormal3x
+glNormal3xOES
+glNormalPointer
+glNormalPointerBounds
+glOrthof
+glOrthofOES
+glOrthox
+glOrthoxOES
+glPixelStorei
+glPointParameterf
+glPointParameterfv
+glPointParameterx
+glPointParameterxOES
+glPointParameterxv
+glPointParameterxvOES
+glPointSize
+glPointSizePointerOES
+glPointSizePointerOESBounds
+glPointSizex
+glPointSizexOES
+glPolygonOffset
+glPolygonOffsetx
+glPolygonOffsetxOES
+glPopMatrix
+glPushMatrix
+glQueryMatrixxOES
+glReadPixels
+glRenderbufferStorageMultisampleIMG
+glRenderbufferStorageOES
+glRotatef
+glRotatex
+glRotatexOES
+glSampleCoverage
+glSampleCoveragex
+glSampleCoveragexOES
+glScalef
+glScalex
+glScalexOES
+glScissor
+glSetFenceNV
+glShadeModel
+glStartTilingQCOM
+glStencilFunc
+glStencilMask
+glStencilOp
+glTestFenceNV
+glTexCoordPointer
+glTexCoordPointerBounds
+glTexEnvf
+glTexEnvfv
+glTexEnvi
+glTexEnviv
+glTexEnvx
+glTexEnvxOES
+glTexEnvxv
+glTexEnvxvOES
+glTexGenfOES
+glTexGenfvOES
+glTexGeniOES
+glTexGenivOES
+glTexGenxOES
+glTexGenxvOES
+glTexImage2D
+glTexParameterf
+glTexParameterfv
+glTexParameteri
+glTexParameteriv
+glTexParameterx
+glTexParameterxOES
+glTexParameterxv
+glTexParameterxvOES
+glTexSubImage2D
+glTranslatef
+glTranslatex
+glTranslatexOES
+glUnmapBufferOES
+glVertexPointer
+glVertexPointerBounds
+glViewport
+glWeightPointerOES
+glWeightPointerOESBounds
+__FINI_ARRAY__
+__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt
new file mode 100644
index 0000000..d86b82c
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt
@@ -0,0 +1,204 @@
+glActiveTexture
+glAttachShader
+glBeginPerfMonitorAMD
+glBindAttribLocation
+glBindBuffer
+glBindFramebuffer
+glBindRenderbuffer
+glBindTexture
+glBindVertexArrayOES
+glBlendColor
+glBlendEquation
+glBlendEquationSeparate
+glBlendFunc
+glBlendFuncSeparate
+glBufferData
+glBufferSubData
+glCheckFramebufferStatus
+glClear
+glClearColor
+glClearDepthf
+glClearStencil
+glColorMask
+glCompileShader
+glCompressedTexImage2D
+glCompressedTexImage3DOES
+glCompressedTexSubImage2D
+glCompressedTexSubImage3DOES
+glCopyTexImage2D
+glCopyTexSubImage2D
+glCopyTexSubImage3DOES
+glCoverageMaskNV
+glCoverageOperationNV
+glCreateProgram
+glCreateShader
+glCullFace
+glDeleteBuffers
+glDeleteFencesNV
+glDeleteFramebuffers
+glDeletePerfMonitorsAMD
+glDeleteProgram
+glDeleteRenderbuffers
+glDeleteShader
+glDeleteTextures
+glDeleteVertexArraysOES
+glDepthFunc
+glDepthMask
+glDepthRangef
+glDetachShader
+glDisable
+glDisableDriverControlQCOM
+glDisableVertexAttribArray
+glDiscardFramebufferEXT
+glDrawArrays
+glDrawElements
+glEGLImageTargetRenderbufferStorageOES
+glEGLImageTargetTexture2DOES
+glEnable
+glEnableDriverControlQCOM
+glEnableVertexAttribArray
+glEndPerfMonitorAMD
+glEndTilingQCOM
+glExtGetBufferPointervQCOM
+glExtGetBuffersQCOM
+glExtGetFramebuffersQCOM
+glExtGetProgramBinarySourceQCOM
+glExtGetProgramsQCOM
+glExtGetRenderbuffersQCOM
+glExtGetShadersQCOM
+glExtGetTexLevelParameterivQCOM
+glExtGetTexSubImageQCOM
+glExtGetTexturesQCOM
+glExtIsProgramBinaryQCOM
+glExtTexObjectStateOverrideiQCOM
+glFinish
+glFinishFenceNV
+glFlush
+glFramebufferRenderbuffer
+glFramebufferTexture2D
+glFramebufferTexture2DMultisampleIMG
+glFramebufferTexture3DOES
+glFrontFace
+glGenBuffers
+glGenFencesNV
+glGenFramebuffers
+glGenPerfMonitorsAMD
+glGenRenderbuffers
+glGenTextures
+glGenVertexArraysOES
+glGenerateMipmap
+glGetActiveAttrib
+glGetActiveUniform
+glGetAttachedShaders
+glGetAttribLocation
+glGetBooleanv
+glGetBufferParameteriv
+glGetBufferPointervOES
+glGetDriverControlStringQCOM
+glGetDriverControlsQCOM
+glGetError
+glGetFenceivNV
+glGetFloatv
+glGetFramebufferAttachmentParameteriv
+glGetIntegerv
+glGetPerfMonitorCounterDataAMD
+glGetPerfMonitorCounterInfoAMD
+glGetPerfMonitorCounterStringAMD
+glGetPerfMonitorCountersAMD
+glGetPerfMonitorGroupStringAMD
+glGetPerfMonitorGroupsAMD
+glGetProgramBinaryOES
+glGetProgramInfoLog
+glGetProgramiv
+glGetRenderbufferParameteriv
+glGetShaderInfoLog
+glGetShaderPrecisionFormat
+glGetShaderSource
+glGetShaderiv
+glGetString
+glGetTexParameterfv
+glGetTexParameteriv
+glGetUniformLocation
+glGetUniformfv
+glGetUniformiv
+glGetVertexAttribPointerv
+glGetVertexAttribfv
+glGetVertexAttribiv
+glHint
+glIsBuffer
+glIsEnabled
+glIsFenceNV
+glIsFramebuffer
+glIsProgram
+glIsRenderbuffer
+glIsShader
+glIsTexture
+glIsVertexArrayOES
+glLineWidth
+glLinkProgram
+glMapBufferOES
+glMultiDrawArraysEXT
+glMultiDrawElementsEXT
+glPixelStorei
+glPolygonOffset
+glProgramBinaryOES
+glReadPixels
+glReleaseShaderCompiler
+glRenderbufferStorage
+glRenderbufferStorageMultisampleIMG
+glSampleCoverage
+glScissor
+glSelectPerfMonitorCountersAMD
+glSetFenceNV
+glShaderBinary
+glShaderSource
+glStartTilingQCOM
+glStencilFunc
+glStencilFuncSeparate
+glStencilMask
+glStencilMaskSeparate
+glStencilOp
+glStencilOpSeparate
+glTestFenceNV
+glTexImage2D
+glTexImage3DOES
+glTexParameterf
+glTexParameterfv
+glTexParameteri
+glTexParameteriv
+glTexSubImage2D
+glTexSubImage3DOES
+glUniform1f
+glUniform1fv
+glUniform1i
+glUniform1iv
+glUniform2f
+glUniform2fv
+glUniform2i
+glUniform2iv
+glUniform3f
+glUniform3fv
+glUniform3i
+glUniform3iv
+glUniform4f
+glUniform4fv
+glUniform4i
+glUniform4iv
+glUniformMatrix2fv
+glUniformMatrix3fv
+glUniformMatrix4fv
+glUnmapBufferOES
+glUseProgram
+glValidateProgram
+glVertexAttrib1f
+glVertexAttrib1fv
+glVertexAttrib2f
+glVertexAttrib2fv
+glVertexAttrib3f
+glVertexAttrib3fv
+glVertexAttrib4f
+glVertexAttrib4fv
+glVertexAttribPointer
+glViewport
+__FINI_ARRAY__
+__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.txt
new file mode 100644
index 0000000..b42d1ee
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.txt
@@ -0,0 +1,52 @@
+slCreateEngine
+slQueryNumSupportedEngineInterfaces
+slQuerySupportedEngineInterfaces
+SL_IID_3DCOMMIT
+SL_IID_3DDOPPLER
+SL_IID_3DGROUPING
+SL_IID_3DLOCATION
+SL_IID_3DMACROSCOPIC
+SL_IID_3DSOURCE
+SL_IID_ANDROIDCONFIGURATION
+SL_IID_ANDROIDEFFECT
+SL_IID_ANDROIDEFFECTCAPABILITIES
+SL_IID_ANDROIDEFFECTSEND
+SL_IID_ANDROIDSIMPLEBUFFERQUEUE
+SL_IID_AUDIODECODERCAPABILITIES
+SL_IID_AUDIOENCODER
+SL_IID_AUDIOENCODERCAPABILITIES
+SL_IID_AUDIOIODEVICECAPABILITIES
+SL_IID_BASSBOOST
+SL_IID_BUFFERQUEUE
+SL_IID_DEVICEVOLUME
+SL_IID_DYNAMICINTERFACEMANAGEMENT
+SL_IID_DYNAMICSOURCE
+SL_IID_EFFECTSEND
+SL_IID_ENGINE
+SL_IID_ENGINECAPABILITIES
+SL_IID_ENVIRONMENTALREVERB
+SL_IID_EQUALIZER
+SL_IID_LED
+SL_IID_METADATAEXTRACTION
+SL_IID_METADATATRAVERSAL
+SL_IID_MIDIMESSAGE
+SL_IID_MIDIMUTESOLO
+SL_IID_MIDITEMPO
+SL_IID_MIDITIME
+SL_IID_MUTESOLO
+SL_IID_NULL
+SL_IID_OBJECT
+SL_IID_OUTPUTMIX
+SL_IID_PITCH
+SL_IID_PLAY
+SL_IID_PLAYBACKRATE
+SL_IID_PREFETCHSTATUS
+SL_IID_PRESETREVERB
+SL_IID_RATEPITCH
+SL_IID_RECORD
+SL_IID_SEEK
+SL_IID_THREADSYNC
+SL_IID_VIBRA
+SL_IID_VIRTUALIZER
+SL_IID_VISUALIZATION
+SL_IID_VOLUME
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.txt
new file mode 100644
index 0000000..80178a3
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.txt
@@ -0,0 +1,150 @@
+AAssetDir_close
+AAssetDir_getNextFileName
+AAssetDir_rewind
+AAssetManager_fromJava
+AAssetManager_open
+AAssetManager_openDir
+AAsset_close
+AAsset_getBuffer
+AAsset_getLength
+AAsset_getRemainingLength
+AAsset_isAllocated
+AAsset_openFileDescriptor
+AAsset_read
+AAsset_seek
+AConfiguration_copy
+AConfiguration_delete
+AConfiguration_diff
+AConfiguration_fromAssetManager
+AConfiguration_getCountry
+AConfiguration_getDensity
+AConfiguration_getKeyboard
+AConfiguration_getKeysHidden
+AConfiguration_getLanguage
+AConfiguration_getMcc
+AConfiguration_getMnc
+AConfiguration_getNavHidden
+AConfiguration_getNavigation
+AConfiguration_getOrientation
+AConfiguration_getScreenLong
+AConfiguration_getScreenSize
+AConfiguration_getSdkVersion
+AConfiguration_getTouchscreen
+AConfiguration_getUiModeNight
+AConfiguration_getUiModeType
+AConfiguration_isBetterThan
+AConfiguration_match
+AConfiguration_new
+AConfiguration_setCountry
+AConfiguration_setDensity
+AConfiguration_setKeyboard
+AConfiguration_setKeysHidden
+AConfiguration_setLanguage
+AConfiguration_setMcc
+AConfiguration_setMnc
+AConfiguration_setNavHidden
+AConfiguration_setNavigation
+AConfiguration_setOrientation
+AConfiguration_setScreenLong
+AConfiguration_setScreenSize
+AConfiguration_setSdkVersion
+AConfiguration_setTouchscreen
+AConfiguration_setUiModeNight
+AConfiguration_setUiModeType
+AInputEvent_getDeviceId
+AInputEvent_getSource
+AInputEvent_getType
+AInputQueue_attachLooper
+AInputQueue_detachLooper
+AInputQueue_finishEvent
+AInputQueue_getEvent
+AInputQueue_hasEvents
+AInputQueue_preDispatchEvent
+AKeyEvent_getAction
+AKeyEvent_getDownTime
+AKeyEvent_getEventTime
+AKeyEvent_getFlags
+AKeyEvent_getKeyCode
+AKeyEvent_getMetaState
+AKeyEvent_getRepeatCount
+AKeyEvent_getScanCode
+ALooper_acquire
+ALooper_addFd
+ALooper_forThread
+ALooper_pollAll
+ALooper_pollOnce
+ALooper_prepare
+ALooper_release
+ALooper_removeFd
+ALooper_wake
+AMotionEvent_getAction
+AMotionEvent_getDownTime
+AMotionEvent_getEdgeFlags
+AMotionEvent_getEventTime
+AMotionEvent_getFlags
+AMotionEvent_getHistoricalEventTime
+AMotionEvent_getHistoricalPressure
+AMotionEvent_getHistoricalSize
+AMotionEvent_getHistoricalX
+AMotionEvent_getHistoricalY
+AMotionEvent_getHistorySize
+AMotionEvent_getMetaState
+AMotionEvent_getOrientation
+AMotionEvent_getPointerCount
+AMotionEvent_getPointerId
+AMotionEvent_getPressure
+AMotionEvent_getRawX
+AMotionEvent_getRawY
+AMotionEvent_getSize
+AMotionEvent_getToolMajor
+AMotionEvent_getToolMinor
+AMotionEvent_getTouchMajor
+AMotionEvent_getTouchMinor
+AMotionEvent_getX
+AMotionEvent_getXOffset
+AMotionEvent_getXPrecision
+AMotionEvent_getY
+AMotionEvent_getYOffset
+AMotionEvent_getYPrecision
+ANativeActivity_finish
+ANativeActivity_hideSoftInput
+ANativeActivity_setWindowFlags
+ANativeActivity_setWindowFormat
+ANativeActivity_showSoftInput
+ANativeWindow_acquire
+ANativeWindow_fromSurface
+ANativeWindow_getFormat
+ANativeWindow_getHeight
+ANativeWindow_getWidth
+ANativeWindow_lock
+ANativeWindow_release
+ANativeWindow_setBuffersGeometry
+ANativeWindow_unlockAndPost
+AObbInfo_delete
+AObbInfo_getFlags
+AObbInfo_getPackageName
+AObbInfo_getVersion
+AObbScanner_getObbInfo
+ASensorEventQueue_disableSensor
+ASensorEventQueue_enableSensor
+ASensorEventQueue_getEvents
+ASensorEventQueue_hasEvents
+ASensorEventQueue_setEventRate
+ASensorManager_createEventQueue
+ASensorManager_destroyEventQueue
+ASensorManager_getDefaultSensor
+ASensorManager_getInstance
+ASensorManager_getSensorList
+ASensor_getMinDelay
+ASensor_getName
+ASensor_getResolution
+ASensor_getType
+ASensor_getVendor
+AStorageManager_delete
+AStorageManager_getMountedObbPath
+AStorageManager_isObbMounted
+AStorageManager_mountObb
+AStorageManager_new
+AStorageManager_unmountObb
+__FINI_ARRAY__
+__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libc.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libc.so.txt
new file mode 100644
index 0000000..6479e95
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libc.so.txt
@@ -0,0 +1,994 @@
+MD5_Final
+MD5_Init
+MD5_Update
+SHA1Final
+SHA1Init
+SHA1Transform
+SHA1Update
+__arc4_getbyte
+__assert
+__assert2
+__atexit_register_cleanup
+__b64_ntop
+__b64_pton
+__brk
+__cxa_atexit
+__cxa_finalize
+__divdi3
+__dn_comp
+__dn_count_labels
+__dn_skipname
+__dorand48
+__dtoa
+__errno
+__evAddTime
+__evCmpTime
+__evConsIovec
+__evConsTime
+__evNowTime
+__evSubTime
+__evTimeSpec
+__evTimeVal
+__evUTCTime
+__fcntl
+__fcntl64
+__findenv
+__fork
+__fp_nquery
+__fp_query
+__fremovelock
+__fstatfs64
+__futex_syscall3
+__futex_syscall4
+__futex_wait
+__futex_wait_ex
+__futex_wake
+__futex_wake_ex
+__get_h_errno
+__get_res_cache
+__get_sp
+__get_stack_base
+__get_thread
+__get_tls
+__getcwd
+__getpriority
+__hostalias
+__init_tls
+__ioctl
+__libc_android_log_assert
+__libc_android_log_print
+__libc_android_log_vprint
+__libc_fini
+__libc_init
+__libc_init_common
+__libc_preinit
+__llseek
+__loc_aton
+__loc_ntoa
+__mmap2
+__moddi3
+__ns_format_ttl
+__ns_get16
+__ns_get32
+__ns_initparse
+__ns_makecanon
+__ns_msg_getflag
+__ns_name_compress
+__ns_name_ntol
+__ns_name_ntop
+__ns_name_pack
+__ns_name_pton
+__ns_name_rollback
+__ns_name_skip
+__ns_name_uncompress
+__ns_name_unpack
+__ns_parserr
+__ns_put16
+__ns_put32
+__ns_samename
+__ns_skiprr
+__ns_sprintrr
+__ns_sprintrrf
+__open
+__openat
+__p_cdname
+__p_cdnname
+__p_class
+__p_fqname
+__p_fqnname
+__p_option
+__p_query
+__p_rcode
+__p_secstodate
+__p_section
+__p_sockun
+__p_time
+__p_type
+__pread64
+__pthread_cleanup_pop
+__pthread_cleanup_push
+__pthread_clone
+__pthread_cond_timedwait
+__pthread_cond_timedwait_relative
+__ptrace
+__putlong
+__putshort
+__pwrite64
+__reboot
+__res_close
+__res_dnok
+__res_get_nibblesuffix
+__res_get_nibblesuffix2
+__res_get_state
+__res_get_static
+__res_getservers
+__res_hnok
+__res_hostalias
+__res_isourserver
+__res_mailok
+__res_nameinquery
+__res_nametoclass
+__res_nametotype
+__res_nclose
+__res_ndestroy
+__res_ninit
+__res_nmkquery
+__res_nopt
+__res_nquery
+__res_nquerydomain
+__res_nsearch
+__res_nsend
+__res_opt
+__res_ourserver_p
+__res_ownok
+__res_pquery
+__res_put_state
+__res_queriesmatch
+__res_querydomain
+__res_randomid
+__res_send
+__res_send_setqhook
+__res_send_setrhook
+__res_setservers
+__res_vinit
+__rt_sigaction
+__rt_sigprocmask
+__rt_sigtimedwait
+__sclose
+__set_errno
+__set_syscall_errno
+__set_thread_area
+__set_tls
+__setresuid
+__setreuid
+__setuid
+__sflags
+__sflush
+__sfp
+__sfvwrite
+__sigsuspend
+__sinit
+__slbexpand
+__smakebuf
+__sread
+__srefill
+__srget
+__sseek
+__stack_chk_fail
+__statfs64
+__swbuf
+__swhatbuf
+__swrite
+__swsetup
+__sym_ntop
+__sym_ntos
+__sym_ston
+__sys_clone
+__syslog
+__system_properties_init
+__system_property_find
+__system_property_find_nth
+__system_property_get
+__system_property_read
+__system_property_wait
+__thread_entry
+__timer_create
+__timer_delete
+__timer_getoverrun
+__timer_gettime
+__timer_settime
+__timer_table_start_stop
+__udivdi3
+__umoddi3
+__wait4
+__waitid
+_cleanup
+_dorand48
+_endhtent
+_exit
+_exit_thread
+_exit_with_stack_teardown
+_fwalk
+_gethtbyaddr
+_gethtbyname
+_gethtbyname2
+_gethtent
+_getlong
+_getshort
+_init_thread
+_longjmp
+_mktemp
+_sethtent
+_setjmp
+_thread_created_hook
+_waitpid
+abort
+accept
+access
+acct
+alarm
+alphasort
+arc4random
+arc4random_addrandom
+arc4random_buf
+arc4random_stir
+arc4random_uniform
+asctime
+asctime64
+asctime64_r
+asctime_r
+asprintf
+atoi
+atol
+atoll
+basename
+basename_r
+bcopy
+bind
+bindresvport
+brk
+bsd_signal
+bsearch
+btowc
+bzero
+calloc
+capget
+capset
+chdir
+chmod
+chown
+chroot
+clearenv
+clearerr
+clock
+clock_getres
+clock_gettime
+clock_nanosleep
+clock_settime
+close
+closedir
+closelog
+closelog_r
+connect
+copy_TM_to_tm
+copy_tm_to_TM
+cpuacct_add
+creat
+ctime
+ctime64
+ctime64_r
+ctime_r
+daemon
+delete_module
+difftime
+dirfd
+dirname
+dirname_r
+div
+dlcalloc
+dlfree
+dlindependent_calloc
+dlindependent_comalloc
+dlmallinfo
+dlmalloc
+dlmalloc_footprint
+dlmalloc_max_footprint
+dlmalloc_stats
+dlmalloc_trim
+dlmalloc_usable_size
+dlmalloc_walk_free_pages
+dlmalloc_walk_heap
+dlmallopt
+dlmemalign
+dlpvalloc
+dlrealloc
+dlvalloc
+dn_expand
+drand48
+dup
+dup2
+endpwent
+endservent
+endusershell
+endutent
+epoll_create
+epoll_ctl
+epoll_wait
+erand48
+err
+errx
+eventfd
+eventfd_read
+eventfd_write
+execl
+execle
+execlp
+execv
+execve
+execvp
+exit
+fchdir
+fchmod
+fchmodat
+fchown
+fchownat
+fclose
+fcntl
+fdatasync
+fdopen
+fdopendir
+fdprintf
+feof
+ferror
+fflush
+fgetc
+fgetln
+fgetpos
+fgets
+fgetwc
+fgetws
+fileno
+flock
+flockfile
+fnmatch
+fopen
+fork
+fpathconf
+fprintf
+fpurge
+fputc
+fputs
+fputwc
+fputws
+fread
+free
+freeaddrinfo
+freedtoa
+freopen
+fscanf
+fseek
+fseeko
+fsetpos
+fstat
+fstatat
+fstatfs
+fsync
+ftell
+ftello
+ftime
+ftok
+ftruncate
+ftrylockfile
+fts_children
+fts_close
+fts_open
+fts_read
+fts_set
+funlockfile
+funopen
+futex
+fwide
+fwprintf
+fwrite
+fwscanf
+gai_strerror
+get_malloc_leak_info
+getaddrinfo
+getc
+getc_unlocked
+getchar
+getchar_unlocked
+getcwd
+getdents
+getdtablesize
+getegid
+getenv
+geteuid
+getgid
+getgrgid
+getgrnam
+getgrouplist
+getgroups
+gethostbyaddr
+gethostbyname
+gethostbyname2
+gethostbyname_r
+gethostent
+gethostname
+getitimer
+getlogin
+getmntent
+getnameinfo
+getnetbyaddr
+getnetbyname
+getopt
+getopt_long
+getopt_long_only
+getpeername
+getpgid
+getpgrp
+getpid
+getppid
+getpriority
+getprotobyname
+getprotobynumber
+getpt
+getpwnam
+getpwuid
+getresgid
+getresuid
+getrlimit
+getrusage
+gets
+getservbyname
+getservbyport
+getservent
+getservent_r
+getsockname
+getsockopt
+gettid
+gettimeofday
+getuid
+getusershell
+getutent
+getwc
+getwchar
+gmtime
+gmtime64
+gmtime64_r
+gmtime_r
+herror
+hstrerror
+if_indextoname
+if_nametoindex
+index
+inet_addr
+inet_aton
+inet_nsap_addr
+inet_nsap_ntoa
+inet_ntoa
+inet_ntop
+inet_pton
+init_module
+initgroups
+inotify_add_watch
+inotify_init
+inotify_rm_watch
+ioctl
+ioprio_get
+ioprio_set
+isalnum
+isalpha
+isascii
+isatty
+isblank
+iscntrl
+isdigit
+isgraph
+islower
+isprint
+ispunct
+issetugid
+isspace
+isupper
+iswalnum
+iswalpha
+iswcntrl
+iswctype
+iswdigit
+iswgraph
+iswlower
+iswprint
+iswpunct
+iswspace
+iswupper
+iswxdigit
+isxdigit
+jrand48
+kill
+killpg
+klogctl
+lchown
+ldexp
+ldiv
+link
+listen
+lldiv
+localtime
+localtime64
+localtime64_r
+localtime_r
+longjmp
+longjmperror
+lrand48
+lseek
+lseek64
+lstat
+madvise
+mallinfo
+malloc
+malloc_debug_init
+mbrlen
+mbrtowc
+mbsinit
+mbsrtowcs
+mbstowcs
+memalign
+memccpy
+memchr
+memcmp
+memcpy
+memmem
+memmove
+memrchr
+memset
+memswap
+mincore
+mkdir
+mkdirat
+mkdtemp
+mknod
+mkstemp
+mkstemps
+mktemp
+mktime
+mktime64
+mlock
+mmap
+mount
+mprotect
+mrand48
+mremap
+msync
+munlock
+munmap
+nanosleep
+nice
+nrand48
+nsdispatch
+open
+openat
+opendir
+openlog
+openlog_r
+pathconf
+pause
+pclose
+perror
+pipe
+pipe2
+poll
+popen
+prctl
+pread
+printf
+pselect
+pthread_attr_destroy
+pthread_attr_getdetachstate
+pthread_attr_getguardsize
+pthread_attr_getschedparam
+pthread_attr_getschedpolicy
+pthread_attr_getscope
+pthread_attr_getstack
+pthread_attr_getstackaddr
+pthread_attr_getstacksize
+pthread_attr_init
+pthread_attr_setdetachstate
+pthread_attr_setguardsize
+pthread_attr_setschedparam
+pthread_attr_setschedpolicy
+pthread_attr_setscope
+pthread_attr_setstack
+pthread_attr_setstackaddr
+pthread_attr_setstacksize
+pthread_cond_broadcast
+pthread_cond_destroy
+pthread_cond_init
+pthread_cond_signal
+pthread_cond_timedwait
+pthread_cond_timedwait_monotonic
+pthread_cond_timedwait_monotonic_np
+pthread_cond_timedwait_relative_np
+pthread_cond_timeout_np
+pthread_cond_wait
+pthread_condattr_destroy
+pthread_condattr_getpshared
+pthread_condattr_init
+pthread_condattr_setpshared
+pthread_create
+pthread_detach
+pthread_equal
+pthread_exit
+pthread_getattr_np
+pthread_getcpuclockid
+pthread_getschedparam
+pthread_getspecific
+pthread_join
+pthread_key_create
+pthread_key_delete
+pthread_kill
+pthread_mutex_destroy
+pthread_mutex_init
+pthread_mutex_lock
+pthread_mutex_lock_timeout_np
+pthread_mutex_trylock
+pthread_mutex_unlock
+pthread_mutexattr_destroy
+pthread_mutexattr_getpshared
+pthread_mutexattr_gettype
+pthread_mutexattr_init
+pthread_mutexattr_setpshared
+pthread_mutexattr_settype
+pthread_once
+pthread_rwlock_destroy
+pthread_rwlock_init
+pthread_rwlock_rdlock
+pthread_rwlock_timedrdlock
+pthread_rwlock_timedwrlock
+pthread_rwlock_tryrdlock
+pthread_rwlock_trywrlock
+pthread_rwlock_unlock
+pthread_rwlock_wrlock
+pthread_rwlockattr_destroy
+pthread_rwlockattr_getpshared
+pthread_rwlockattr_init
+pthread_rwlockattr_setpshared
+pthread_self
+pthread_setname_np
+pthread_setschedparam
+pthread_setspecific
+pthread_sigmask
+ptrace
+ptsname
+ptsname_r
+putc
+putc_unlocked
+putchar
+putchar_unlocked
+putenv
+puts
+pututline
+putw
+putwc
+putwchar
+pwrite
+qsort
+raise
+read
+readdir
+readdir_r
+readlink
+readv
+realloc
+realpath
+reboot
+recv
+recvfrom
+recvmsg
+regcomp
+regerror
+regexec
+regfree
+remove
+rename
+renameat
+res_init
+res_mkquery
+res_need_init
+res_query
+res_search
+rewind
+rewinddir
+rmdir
+sbrk
+scandir
+scanf
+sched_get_priority_max
+sched_get_priority_min
+sched_getparam
+sched_getscheduler
+sched_rr_get_interval
+sched_setparam
+sched_setscheduler
+sched_yield
+seed48
+select
+sem_close
+sem_destroy
+sem_getvalue
+sem_init
+sem_open
+sem_post
+sem_timedwait
+sem_trywait
+sem_unlink
+sem_wait
+send
+sendfile
+sendmsg
+sendto
+setbuf
+setbuffer
+setegid
+setenv
+seteuid
+setgid
+setgroups
+setitimer
+setjmp
+setlinebuf
+setlocale
+setlogmask
+setlogmask_r
+setpgid
+setpgrp
+setpriority
+setregid
+setresgid
+setresuid
+setreuid
+setrlimit
+setservent
+setsid
+setsockopt
+settimeofday
+setuid
+setusershell
+setutent
+setvbuf
+shutdown
+sigaction
+sigaltstack
+sigblock
+siginterrupt
+sigpending
+sigprocmask
+sigsetmask
+sigsuspend
+sigwait
+sleep
+snprintf
+socket
+socketpair
+sprintf
+srand48
+sscanf
+stat
+statfs
+strcasecmp
+strcasestr
+strcat
+strchr
+strcmp
+strcoll
+strcpy
+strcspn
+strdup
+strerror
+strerror_r
+strftime
+strftime_tz
+strlcat
+strlcpy
+strlen
+strncasecmp
+strncat
+strncmp
+strncpy
+strndup
+strnlen
+strntoimax
+strntoumax
+strpbrk
+strptime
+strrchr
+strsep
+strsignal
+strspn
+strstr
+strtod
+strtoimax
+strtok
+strtok_r
+strtol
+strtoll
+strtotimeval
+strtoul
+strtoull
+strtoumax
+strxfrm
+swprintf
+swscanf
+symlink
+sync
+syscall
+sysconf
+sysinfo
+syslog
+syslog_r
+system
+sysv_signal
+tcgetpgrp
+tcsetpgrp
+tempnam
+time
+timegm64
+timelocal64
+timer_create
+timer_delete
+timer_getoverrun
+timer_gettime
+timer_settime
+times
+tkill
+tmpfile
+tmpnam
+toascii
+tolower
+toupper
+towlower
+towupper
+truncate
+ttyname
+ttyname_r
+tzset
+umask
+umount
+umount2
+uname
+ungetc
+ungetwc
+unlink
+unlinkat
+unlockpt
+unsetenv
+usleep
+utime
+utimes
+utmpname
+valid_tm_mon
+valid_tm_wday
+valloc
+vasprintf
+verr
+verrx
+vfdprintf
+vfork
+vfprintf
+vfscanf
+vfwprintf
+vprintf
+vscanf
+vsnprintf
+vsprintf
+vsscanf
+vswprintf
+vsyslog
+vsyslog_r
+vwarn
+vwarnx
+vwprintf
+wait
+wait3
+waitid
+waitpid
+warn
+warnx
+wcpcpy
+wcpncpy
+wcrtomb
+wcscasecmp
+wcscat
+wcschr
+wcscmp
+wcscoll
+wcscpy
+wcscspn
+wcsdup
+wcsftime
+wcslcat
+wcslcpy
+wcslen
+wcsncasecmp
+wcsncat
+wcsncmp
+wcsncpy
+wcsnlen
+wcspbrk
+wcsrchr
+wcsrtombs
+wcsspn
+wcsstr
+wcstod
+wcstok
+wcstol
+wcstombs
+wcstoul
+wcswcs
+wcswidth
+wcsxfrm
+wctob
+wctype
+wcwidth
+wmemchr
+wmemcmp
+wmemcpy
+wmemmove
+wmemset
+wprintf
+write
+writev
+wscanf
+_C_ctype_
+_C_tolower_
+_C_toupper_
+__FINI_ARRAY__
+__INIT_ARRAY__
+__atexit
+__atexit_invalid
+__bionic_brk
+__evOptMonoTime
+__isthreaded
+__libc_malloc_default_dispatch
+__libc_malloc_dispatch
+__p_cert_syms
+__p_class_syms
+__p_default_section_syms
+__p_key_syms
+__p_rcode_syms
+__p_type_syms
+__p_update_section_syms
+__page_shift
+__page_size
+__progname
+__rand48_add
+__rand48_mult
+__rand48_seed
+__sF
+__sFext
+__sdidinit
+__sglue
+__stack_chk_guard
+__system_property_area__
+_ctype_
+_nres
+_ns_flagdata
+_rand48_add
+_rand48_mult
+_rand48_seed
+_res_opcodes
+_tolower_tab_
+_toupper_tab_
+daylight
+environ
+h_errlist
+h_nerr
+optarg
+opterr
+optind
+optopt
+optreset
+sys_siglist
+sys_signame
+timezone
+tzname
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libdl.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libdl.so.txt
new file mode 100644
index 0000000..24de29a
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libdl.so.txt
@@ -0,0 +1,8 @@
+dl_iterate_phdr
+dladdr
+dlclose
+dlerror
+dlopen
+dlsym
+__FINI_ARRAY__
+__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt
new file mode 100644
index 0000000..9cbc8c2
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt
@@ -0,0 +1,5 @@
+AndroidBitmap_getInfo
+AndroidBitmap_lockPixels
+AndroidBitmap_unlockPixels
+__FINI_ARRAY__
+__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt b/ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt
new file mode 100644
index 0000000..1405a81
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt
@@ -0,0 +1,10 @@
+__android_log_assert
+__android_log_btwrite
+__android_log_buf_print
+__android_log_buf_write
+__android_log_bwrite
+__android_log_dev_available
+__android_log_print
+__android_log_vprint
+__android_log_write
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libm.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libm.so.txt
new file mode 100644
index 0000000..349f00f
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libm.so.txt
@@ -0,0 +1,190 @@
+__exp__D
+__fedisableexcept
+__feenableexcept
+__fpclassifyd
+__fpclassifyf
+__fpclassifyl
+__ieee754_rem_pio2
+__ieee754_rem_pio2f
+__isfinite
+__isfinitef
+__isfinitel
+__isinf
+__isinff
+__isinfl
+__isnanl
+__isnormal
+__isnormalf
+__isnormall
+__kernel_cos
+__kernel_cosdf
+__kernel_rem_pio2
+__kernel_sin
+__kernel_sindf
+__kernel_tan
+__kernel_tandf
+__log__D
+__signbit
+__signbitf
+__signbitl
+__test_sse
+acos
+acosf
+acosh
+acoshf
+asin
+asinf
+asinh
+asinhf
+atan
+atan2
+atan2f
+atanf
+atanh
+atanhf
+cbrt
+cbrtf
+ceil
+ceilf
+ceill
+copysign
+copysignf
+copysignl
+cos
+cosf
+cosh
+coshf
+drem
+dremf
+erf
+erfc
+erfcf
+erff
+exp
+exp2
+exp2f
+expf
+expm1
+expm1f
+fabs
+fabsf
+fabsl
+fdim
+fdimf
+fdiml
+fegetenv
+feholdexcept
+feraiseexcept
+fesetexceptflag
+feupdateenv
+finite
+finitef
+floor
+floorf
+floorl
+fma
+fmaf
+fmax
+fmaxf
+fmaxl
+fmin
+fminf
+fminl
+fmod
+fmodf
+frexp
+frexpf
+gamma
+gamma_r
+gammaf
+gammaf_r
+hypot
+hypotf
+ilogb
+ilogbf
+ilogbl
+isnan
+isnanf
+j0
+j0f
+j1
+j1f
+jn
+jnf
+ldexpf
+ldexpl
+lgamma
+lgamma_r
+lgammaf
+lgammaf_r
+llrint
+llrintf
+llround
+llroundf
+llroundl
+log
+log10
+log10f
+log1p
+log1pf
+logb
+logbf
+logf
+lrint
+lrintf
+lround
+lroundf
+lroundl
+modf
+modff
+nearbyint
+nearbyintf
+nextafter
+nextafterf
+nexttowardf
+pow
+powf
+remainder
+remainderf
+remquo
+remquof
+rint
+rintf
+round
+roundf
+roundl
+scalb
+scalbf
+scalbn
+scalbnf
+scalbnl
+significand
+significandf
+sin
+sincos
+sincosf
+sincosl
+sinf
+sinh
+sinhf
+sqrt
+sqrtf
+tan
+tanf
+tanh
+tanhf
+tgamma
+trunc
+truncf
+truncl
+y0
+y0f
+y1
+y1f
+yn
+ynf
+__FINI_ARRAY__
+__INIT_ARRAY__
+__fe_dfl_env
+__has_sse
+signgam
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt
new file mode 100644
index 0000000..920262d
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt
@@ -0,0 +1,26 @@
+_ZN9type_infoC1ERKS_
+_ZN9type_infoC1Ev
+_ZN9type_infoC2ERKS_
+_ZN9type_infoC2Ev
+_ZN9type_infoD0Ev
+_ZN9type_infoD1Ev
+_ZN9type_infoD2Ev
+_ZNK9type_info4nameEv
+_ZNK9type_info6beforeERKS_
+_ZNK9type_infoeqERKS_
+_ZNK9type_infoneERKS_
+_ZdaPv
+_ZdaPvRKSt9nothrow_t
+_ZdlPv
+_ZdlPvRKSt9nothrow_t
+_Znaj
+_ZnajRKSt9nothrow_t
+_Znwj
+_ZnwjRKSt9nothrow_t
+__cxa_guard_abort
+__cxa_guard_acquire
+__cxa_guard_release
+__cxa_pure_virtual
+_ZSt7nothrow
+__FINI_ARRAY__
+__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libz.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libz.so.txt
new file mode 100644
index 0000000..e35c7af
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libz.so.txt
@@ -0,0 +1,76 @@
+adler32
+adler32_combine
+adler32_combine64
+compress
+compress2
+compressBound
+crc32
+crc32_combine
+crc32_combine64
+deflate
+deflateBound
+deflateCopy
+deflateEnd
+deflateInit2_
+deflateInit_
+deflateParams
+deflatePrime
+deflateReset
+deflateSetDictionary
+deflateSetHeader
+deflateTune
+get_crc_table
+gzbuffer
+gzclearerr
+gzclose
+gzclose_r
+gzclose_w
+gzdirect
+gzdopen
+gzeof
+gzerror
+gzflush
+gzgetc
+gzgets
+gzoffset
+gzoffset64
+gzopen
+gzopen64
+gzprintf
+gzputc
+gzputs
+gzread
+gzrewind
+gzseek
+gzseek64
+gzsetparams
+gztell
+gztell64
+gzungetc
+gzwrite
+inflate
+inflateBack
+inflateBackEnd
+inflateBackInit_
+inflateCopy
+inflateEnd
+inflateGetHeader
+inflateInit2_
+inflateInit_
+inflateMark
+inflatePrime
+inflateReset
+inflateReset2
+inflateSetDictionary
+inflateSync
+inflateSyncPoint
+inflateUndermine
+uncompress
+zError
+zlibCompileFlags
+zlibVersion
+__FINI_ARRAY__
+__INIT_ARRAY__
+deflate_copyright
+inflate_copyright
+z_errmsg
diff --git a/ndk/platforms/android-9/include/android/input.h b/ndk/platforms/android-9/include/android/input.h
index 7df13c3..9449574 100644
--- a/ndk/platforms/android-9/include/android/input.h
+++ b/ndk/platforms/android-9/include/android/input.h
@@ -485,7 +485,7 @@
/* Get the current pressure of this event for the given pointer index.
* The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * however values higher than 1 may be generated depending on the calibration of
+ * although values higher than 1 may be generated depending on the calibration of
* the input device. */
float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);
@@ -545,7 +545,8 @@
* and views.
* Whole numbers are pixels; the value may have a fraction for input devices
* that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index);
+float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index,
+ size_t history_index);
/* Get the historical raw Y coordinate of this event for the given pointer index that
* occurred between this event and the previous motion event.
@@ -554,7 +555,8 @@
* and views.
* Whole numbers are pixels; the value may have a fraction for input devices
* that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index);
+float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index,
+ size_t history_index);
/* Get the historical X coordinate of this event for the given pointer index that
* occurred between this event and the previous motion event.
@@ -573,7 +575,7 @@
/* Get the historical pressure of this event for the given pointer index that
* occurred between this event and the previous motion event.
* The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * however values higher than 1 may be generated depending on the calibration of
+ * although values higher than 1 may be generated depending on the calibration of
* the input device. */
float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
size_t history_index);
diff --git a/ndk/platforms/android-9/include/pthread.h b/ndk/platforms/android-9/include/pthread.h
index 1e80b12..5e87043 100644
--- a/ndk/platforms/android-9/include/pthread.h
+++ b/ndk/platforms/android-9/include/pthread.h
@@ -235,7 +235,7 @@
void* reserved[4]; /* for future extensibility */
} pthread_rwlock_t;
-#define PTHREAD_RWLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, NULL, 0, 0 }
+#define PTHREAD_RWLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0, 0, 0, { NULL, NULL, NULL, NULL } }
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
diff --git a/ndk/platforms/android-9/include/unistd.h b/ndk/platforms/android-9/include/unistd.h
index 29154a2..21154ad 100644
--- a/ndk/platforms/android-9/include/unistd.h
+++ b/ndk/platforms/android-9/include/unistd.h
@@ -133,7 +133,7 @@
extern ssize_t read(int, void *, size_t);
extern ssize_t write(int, const void *, size_t);
extern ssize_t pread(int, void *, size_t, off_t);
-extern ssize_t pwrite(int, void *, size_t, off_t);
+extern ssize_t pwrite(int, const void *, size_t, off_t);
extern int dup(int);
extern int dup2(int, int);
diff --git a/ndk/sources/android/native_app_glue/android_native_app_glue.c b/ndk/sources/android/native_app_glue/android_native_app_glue.c
index fbd42b4..3069f17 100644
--- a/ndk/sources/android/native_app_glue/android_native_app_glue.c
+++ b/ndk/sources/android/native_app_glue/android_native_app_glue.c
@@ -106,10 +106,7 @@
case APP_CMD_TERM_WINDOW:
LOGI("APP_CMD_TERM_WINDOW\n");
- pthread_mutex_lock(&android_app->mutex);
- android_app->window = NULL;
pthread_cond_broadcast(&android_app->cond);
- pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_RESUME:
diff --git a/pdk/README b/pdk/README
index d9f8996..0acb1eb 100644
--- a/pdk/README
+++ b/pdk/README
@@ -11,7 +11,7 @@
If that doesn't work, go through the instructions on
- http://source.android.com/download again.
+ http://source.android.com/source/download.html again.
2) from the root
diff --git a/pdk/docs/about/index.jd b/pdk/docs/about/index.jd
index 2f98b65..43d2a8d 100644
--- a/pdk/docs/about/index.jd
+++ b/pdk/docs/about/index.jd
@@ -3,10 +3,10 @@
doc.hidenav=true
@jd:body
<p>Android is an open-source software stack created for mobile phones and
-other devices. The Android Open Source Project (AOSP) is tasked with the
-maintenance and further development of Android. Many device manufacturers have
-brought to market devices running Android, and they are readibly available
-around the world.</p>
+other devices. The Android Open Source Project (AOSP), led by Google, is
+tasked with the maintenance and further development of Android. Many device
+manufacturers have brought to market devices running Android, and they are
+readibly available around the world.</p>
<p>Our primary purpose is to build an excellent software platform for everyday
users. A number of companies have committed many engineers to achieve this
goal, and the result is a full production quality consumer product whose
diff --git a/pdk/docs/about/philosophy.jd b/pdk/docs/about/philosophy.jd
index 1aa1ccf..1562e42 100644
--- a/pdk/docs/about/philosophy.jd
+++ b/pdk/docs/about/philosophy.jd
@@ -2,7 +2,7 @@
doc.type=about
doc.hidenav=true
@jd:body
-<p>Android is an open-source software stack for mobile phones and similar
+<p>Android is an open-source software stack for mobile phones and other
devices.</p>
<h2>Origin and Goal</h2>
<p>Android was originated by a group of companies known as the Open Handset
@@ -16,12 +16,11 @@
ideas a reality. We wanted to make sure that there was no central point of
failure, where one industry player could restrict or control the innovations
of any other. The solution we chose was an open and open-source platform.</p>
-<p>But the ultimate goal, of course, is to improve the mobile experience for
-real users by facilitating innovation. Accordingly, the primary goal of the
-AOSP is to make sure Android is a success as an end user product.</p>
+<p>The goal of the Android Open Source Project is to create a successful
+real-world product that improves the mobile experience for end users.</p>
<h2>Governance Philosophy</h2>
<p>The companies that have invested in Android have done so on its merits,
-because we collectively believe that an open platform is necessary. Android is
+because we believe that an open platform is necessary. Android is
intentionally and explicitly an open-source -- as opposed to free software --
effort: a group of organizations with shared needs has pooled
resources to collaborate on a single implementation of a shared product.
@@ -34,20 +33,19 @@
Anyone can (and will!) use the Android source code for any purpose, and we
welcome all such uses. However, in order to take part in the shared
ecosystem of applications that we are building around Android, device builders
-can take advantage of the Compatibility Program.</p>
+must participate in the Compatibility Program.</p>
<p>Though Android consists of multiple sub-projects, this is strictly a
project-management technique. We view and manage Android as a single,
holistic software product, not a "distribution", specification, or collection
-of replaceable parts. Conceptually, our notion is that device builders port
+of replaceable parts. Our intent is that device builders port
Android to a device; they don't implement a specification or curate a
distribution.</p>
<h2>How We Work</h2>
<p>We know that quality does not come without hard work. Along with many
partners, Google has contributed full-time engineers, product managers, UI
designers, Quality Assurance, and all the other roles required to bring
-modern devices to market. We integrate the open source administration and
+modern devices to market. We roll the open source administration and
maintenance into the larger product development cycle.</p>
-<p>In a nutshell:</p>
<ul>
<li>At any given moment, there is a current latest release of the Android
platform. This typically takes the form of a branch in the tree.</li>
@@ -56,18 +54,9 @@
features, and so on.</li>
<li>In parallel, Google works internally on the next version of the
Android platform and framework, working according to the product's needs and
-goals. Some of the work from the current latest tree will promoted into these
-releases.</li>
-<li>When the "n+1"th version is determined to be nearing completion, it will
-be published to the public source tree, and become the new latest
-release.</li>
-<li>Since Android is open source, nothing prevents device implementers from
-shipping devices on older (obsolete) Android builds. However, active work will
-be focused on the current platform release.</li>
+goals. We develop the next version of Android by working with a device partner
+on a flagship device whose specifications are chosen to push Android
+in the direction we believe it should go.</li>
+<li>When the "n+1"th version is ready, it will be published to the public
+source tree, and become the new latest release.</li>
</ul>
-<p>To meet our goals, Android needs to achieve widespread, compatible
-adoption. We believe that the best way to accomplish that is to make sure that
-we ship high-quality, flagship devices with an intense product and end-user
-focus. The "next release" of Android is driven by the product needs for the next
-generation of mobile devices; the resulting excellent product is then released
-to open source and becomes the new current version of the platform.</p>
diff --git a/pdk/docs/community/groups-charter.jd b/pdk/docs/community/groups-charter.jd
index 6d5b501..959917e 100644
--- a/pdk/docs/community/groups-charter.jd
+++ b/pdk/docs/community/groups-charter.jd
@@ -1,26 +1,66 @@
page.title=Android Discussion Groups Charter
doc.type=community
+doc.hidenav=true
@jd:body
-<h2>
-Audience
-</h2>
-<p>These discussion groups are intended for developers working with the Android platform. Everyone is welcome to join in, provided you follow our community's policies described below. Our users help each other, and many experts post to these groups, including members of the Open Handset Alliance.
+<h2>Audience</h2>
+<p>These discussion groups are intended for developers working with the
+Android platform. Everyone is welcome to join in, provided you follow our
+community's policies described below. Our users help each other, and many
+experts post to these groups, including members of the Open Handset Alliance.
</p>
-<p>No topic is off-limits, provided it relates to Android in some way. However, since these are very busy lists, search the archives before posting your question; you may find your question has already been answered.
+<p>No topic is off-limits, provided it relates to Android in some way.
+However, since these are very busy lists, search the archives before posting
+your question; you may find your question has already been answered.
</p>
-<h2>
-Mailing list rules
-</h2>
-<p>We love simplicity and hate restrictions, so we keep our policies minimal. The rules below describe what's expected of subscribers to the Android mailing lists.
+<h2>Mailing list rules</h2>
+<p>We love simplicity and hate restrictions, so we keep our policies minimal.
+The rules below describe what's expected of subscribers to the Android mailing
+lists.
</p>
<ul><li><b>Please be friendly</b>
-<br>Showing courtesy and respect to others is a vital part of the Android culture, and we expect everyone participating in the Android community to join us in accepting nothing less. Being courteous does not mean we can't constructively disagree with each other, but it does mean that we must be polite when we do so. There's never a reason to be antagonistic or dismissive toward anyone; if you think there is, think again before you post.<br><br>Mobile development is serious business, but it's also a lot of fun. Let's keep it that way. Let's strive to be one of the friendliest communities in all of open source.<br><br></li>
+<br>Showing courtesy and respect to others is a vital part of the Android
+culture, and we expect everyone participating in the Android community to join
+us in accepting nothing less. Being courteous does not mean we can't
+constructively disagree with each other, but it does mean that we must be
+polite when we do so. There's never a reason to be antagonistic or dismissive
+toward anyone; if you think there is, think again before you
+post.<br><br>Mobile development is serious business, but it's also a lot of
+fun. Let's keep it that way. Let's strive to be one of the friendliest
+communities in all of open source.<br><br></li>
+
<li><b>Allowed discussion topics</b>
-<br>Most topics are technical discussions of Android or users helping each other, but this group is intended for discussions of<i>everything</i>
-in the world of Android. We welcome announcements and discussion of products, libraries, publications, and other interesting Android-related news. We even welcome (polite!) discussion of articles and ideas critical of Android--after all, we can't improve if we don't listen. There are no restrictions on the subject matter, and we don't exclude discussions of commercial products if users are interested in talking about them.<br><br>However, we hate spam almost as passionately as we love courtesy and respect, so we reserve the right to limit discussions that amount to spam. Outright spam will result in the spammer being immediately and permanently banned from the list.
+<br>Most of our groups are for technical discussions of Android or users
+helping each other. Generally we don't put hard restrictions on the topics
+discussed in the group: as long as the topic is relevant to Android in some
+way, it's welcome on our groups. We welcome announcements and discussion of
+products, libraries, publications, and other interesting Android-related news,
+but <b>please do not cross-post</b>. Post only to the most relevant group for
+your message. We even welcome (polite!) discussion of articles and ideas
+critical of Android--after all, we can't improve if we don't listen.<br><br>
</li>
+
+<li><b>Working Lists</b>
+<br>Some of our groups are considered "working lists", by which we mean that the
+list is intended to be used in support of the completion of specific tasks. On
+these groups, we don't welcome off-topic conversations, and will generally ask
+you to take general discussions to a different list. Since these are lists
+where people are trying to get work done, we will be pretty aggressive about
+keeping the noise level low. We ask that you respect our contributors' time
+and keep general discussions to appropriate lists.<br><br>
+</li>
+
+<li><b>Spam</b>
+<br>We hate spam almost as passionately as we love courtesy and respect, so we
+reserve the right to limit discussions that amount to spam. Outright spam will
+result in the spammer being immediately and permanently banned from the list.
+<br><br></li>
</ul>
-<p>The most important rule is friendliness. Remember: disrespect and rudeness are not welcome in our community under any circumstances. We don't have a formal policy on dealing with troublemakers, and we hope we never need one.That said, we do pledge to do our best to be fair, and we will always try to warn someone before banning him or her.
+
+<p>The most important rule is friendliness. Remember: disrespect and rudeness
+are not welcome in our community under any circumstances. We don't have a
+formal policy on dealing with troublemakers, and we hope we never need
+one.That said, we do pledge to do our best to be fair, and we will always try
+to warn someone before banning him or her.
</p>
<h2>
Contacting the moderators
diff --git a/pdk/docs/community/index.jd b/pdk/docs/community/index.jd
index 6e6f59e..46adf37 100644
--- a/pdk/docs/community/index.jd
+++ b/pdk/docs/community/index.jd
@@ -1,7 +1,7 @@
-page.title=Community
+page.title=Android Community
doc.type=community
+doc.hidenav=true
@jd:body
-<h1>Android Community</h1>
<p>Welcome to the Android community!</p>
<p>The key to any community is, obviously, communication. Like most projects,
Android communicates via mailing lists. Because Android is an extremely large
@@ -37,6 +37,14 @@
<h2>Open Source Project discussions</h2>
<ul>
+<li><b>android-platform</b><br/>
+This list is for general discussion about the Android open-source project or
+the platform technologies.<br/><br/>
+Subscribe using Google Groups: <a
+href="http://groups.google.com/group/android-platform">android-platform</a><br/>
+Subscribe via email: <a href="mailto:android-platform+subscribe@googlegroups.com">android-platform+subscribe@googlegroups.com</a>
+</li>
+
<li><b>android-building</b><br/>
Subscribe to this list for discussion and help on building the Android source
code, and on the build system. If you've just checked out the source code and
@@ -58,14 +66,14 @@
Subscribe via email: <a href="mailto:android-porting+subscribe@googlegroups.com">android-porting+subscribe@googlegroups.com</a>
</li>
-<li><b>android-platform</b><br/>
-This list is for developers who want to contribute code to the Android
-user-space projects, such as the core system libraries, the Android
-services, the public APIs, or the built-in applications. Note: contributors
+<li><b>android-contrib</b><br/>
+This list is for developers who want to contribute code to Android. This is a
+working list, and is not appropriate for general discussion. We ask that
+general discussion go to android-platform. Note: contributors
to the Android kernel should go to the android-kernel list, below.<br/><br/>
Subscribe using Google Groups: <a
-href="http://groups.google.com/group/android-platform">android-platform</a><br/>
-Subscribe via email: <a href="mailto:android-platform+subscribe@googlegroups.com">android-platform+subscribe@googlegroups.com</a>
+href="http://groups.google.com/group/android-contrib">android-contrib</a><br/>
+Subscribe via email: <a href="mailto:android-contrib+subscribe@googlegroups.com">android-contrib+subscribe@googlegroups.com</a>
</li>
<li><b>android-kernel</b><br/>
@@ -88,27 +96,35 @@
under "subscribe via email" in the lists above.</p>
<p>To set up how you receive mailing list postings by email:</p>
<ol>
-<li>Sign into the group via the Google Groups site. For example, for the android-framework group you would
-visit <a
-href="http://groups.google.com/group/android-framework">http://groups.google.com/group/android-framework</a>.</li>
+<li>Sign into the group via the Google Groups site. For example, for the android-platform group you would
+visit <a href="http://groups.google.com/group/android-platform">http://groups.google.com/group/android-platform</a>.</li>
<li>Click "Edit my membership" on the right side.</li>
<li>Under "How do you want to read this group?" select one of the email options.</li>
</ol>
<h2>Android on IRC</h2>
-<p>We also have a presence on IRC via Freenode. We maintain two official IRC
-channels on irc.freenode.net:</p>
+<p>We also have a presence on IRC via <a href="http://freenode.net/">freenode</a>.
+We maintain two official IRC channels on
+<a href="irc://irc.freenode.net/">irc.freenode.net</a> (access via the web
+at <a href="http://webchat.freenode.net/">freenode webchat</a>):</p>
<ul>
-<li><b>#android</b> - dedicated to general Android discussion and porting concerns</li>
-<li><b>#android-dev</b> - dedicated to discussion about writing Android applications</li>
+<li><b><a href="irc://irc.freenode.net/android">#android</a></b>
+ — dedicated to general Android discussion and porting concerns</li>
+<li><b><a href="irc://irc.freenode.net/android-dev">#android-dev</a></b>
+ — dedicated to discussion about writing Android applications</li>
</ul>
<p>The channels above are official. There are a few other channels the
community is using, but are not official. These aren't official or officially
moderated/managed, so you use the channels below at your own risk. The Open
Handset Alliance doesn't endorse these channels, there's no warranty express
-or implied, and so on. There may be more.</p>
+or implied, and so on. There may be more channels than just these listed.</p>
<ul>
-<li><b>#android-offtopic</b> - for, well, off-topic discussions</li>
-<li><b>#android-root</b> - for discussion related to off-label uses of hardware</li>
-<li><b>#androidfra</b> - pour discuter d'Android en français</li>
+<li><b><a href="irc://irc.freenode.net/android-firehose">#android-firehose</a></b>
+ — displays in real-time the commits to the Android Open Source Project</li>
+<li><b><a href="irc://irc.freenode.net/android-fr">#android-fr</a></b>
+ — pour discuter d'Android en français</li>
+<li><b><a href="irc://irc.freenode.net/android-offtopic">#android-offtopic</a></b>
+ — for, well, off-topic discussions</li>
+<li><b><a href="irc://irc.freenode.net/android-root">#android-root</a></b>
+ — for discussion related to off-label uses of hardware</li>
</ul>
diff --git a/pdk/docs/compatibility/2.1/versions.jd b/pdk/docs/compatibility/2.1/versions.jd
new file mode 100644
index 0000000..9687a96
--- /dev/null
+++ b/pdk/docs/compatibility/2.1/versions.jd
@@ -0,0 +1,19 @@
+page.title=Permitted Version Strings for Android 2.1
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.1-cdd.pdf">Android 2.1 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.1-based system. The only permitted values for
+<code>android.os.Build.VERSION.RELEASE</code> for Android 2.1 are:</p>
+<ul>
+<li>2.1</li>
+<li>2.1-update1</li>
+</ul>
diff --git a/pdk/docs/compatibility/2.2/versions.jd b/pdk/docs/compatibility/2.2/versions.jd
new file mode 100644
index 0000000..87b12eb
--- /dev/null
+++ b/pdk/docs/compatibility/2.2/versions.jd
@@ -0,0 +1,20 @@
+page.title=Permitted Version Strings for Android 2.2
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.2-cdd.pdf">Android 2.2 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.2-based system.</p>
+<p>The value of <code>android.os.Build.VERSION.RELEASE</code> for Android 2.2
+MUST be one of the following strings:</p>
+<ul>
+<li>2.2</li>
+<li>2.2.1</li>
+</ul>
diff --git a/pdk/docs/compatibility/2.3/versions.jd b/pdk/docs/compatibility/2.3/versions.jd
new file mode 100644
index 0000000..5f634ed
--- /dev/null
+++ b/pdk/docs/compatibility/2.3/versions.jd
@@ -0,0 +1,20 @@
+page.title=Permitted Version Strings for Android 2.3
+doc.type=compatibility
+@jd:body
+<p>As described in Section 3.2.2 of the <a
+href="{@docRoot}compatibility/android-2.3-cdd.pdf">Android 2.3 Compatibility
+Definition</a>, only certain strings are allowable for the system property
+<code>android.os.Build.VERSION.RELEASE</code>. The reason for this is that
+applications and web sites may rely on predictable values for this string, and
+so that end users can easily and reliably identify the version of Android
+running on their devices.</p>
+<p>Because subsequent releases of the Android software may revise this string,
+but not change any API behavior, such releases may not be accompanied by a new
+Compatibility Definition Document. This page lists the versions that are
+allowable by an Android 2.2-based system.</p>
+<p>The value of <code>android.os.Build.VERSION.RELEASE</code> for Android 2.3
+MUST be one of the following strings:</p>
+<ul>
+<li>2.3</li>
+<li>2.3.1</li>
+</ul>
diff --git a/pdk/docs/compatibility/android-1.6-cdd.pdf b/pdk/docs/compatibility/android-1.6-cdd.pdf
new file mode 100644
index 0000000..ba7b4ad
--- /dev/null
+++ b/pdk/docs/compatibility/android-1.6-cdd.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/android-2.1-cdd.pdf b/pdk/docs/compatibility/android-2.1-cdd.pdf
new file mode 100644
index 0000000..7fe54c6
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.1-cdd.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/android-2.2-cdd.pdf b/pdk/docs/compatibility/android-2.2-cdd.pdf
new file mode 100644
index 0000000..fbc1e77
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.2-cdd.pdf
@@ -0,0 +1,4080 @@
+%PDF-1.4
+% ReportLab Generated PDF document http://www.reportlab.com
+% 'BasicFonts': class PDFDictionary
+1 0 obj
+% The standard fonts dictionary
+<< /F1 2 0 R
+ /F2 4 0 R
+ /F3 105 0 R
+ /F4 107 0 R >>
+endobj
+% 'F1': class PDFType1Font
+2 0 obj
+% Font Helvetica
+<< /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'FormXob.a31102908a592e8f94c7b4e032ffcc37': class PDFImageXObject
+3 0 obj
+<< /BitsPerComponent 8
+ /ColorSpace /DeviceRGB
+ /Filter [ /ASCII85Decode
+ /DCTDecode ]
+ /Height 49
+ /Length 11548
+ /Subtype /Image
+ /Type /XObject
+ /Width 369 >>
+stream
+s4IA0!"_al8O`[\!<<*#!!*'"s5F.Y8OGjP:f:(Y8PDPQ!<E0#"70H8E,5RU!!$kRFE18L66KB5=s+('!!3-/!"JuF!'"CsF)XEA:eUihzzzzzzp=93Ezdk,!IE,5LSzzzzzzzzzzz!"O$O=]te*!A"3N!#0'J=]te*!C-Vb!#/mE=]te*!E9%!!#0X!E-)'[!GDH5!#/pV@:T?<!IOkI!%`.i;F:Ea!N5tu!"NX@;F:Ea!Or+0!"NI;;F:Ea!QY6@!"O0^B64+R!S@AP!&/;$Bl3nN!XJc+!'"M#F(51M!^H_c!+]V]@r22G!i,er!;^PLDe&hJ"/#Vo!%;>rEc_9]"3:HB!$kZL=s*eFzS#-/c9N;&m!jGd0=s*eFz2.HUdTBcIW)6m:H=s*eFz--ZDi'@d'_[`)?O=s*eFzo@O$D!!!!"('ntn1GSq1!!!!"$b$*9"d]2go2bnl#:TWQrR_)LqmZV*rMBPp"53_T_"M8\EcqE_z!!*,F!!$MOEcqE_z!!*,F!!$MOEcqE_z!!*,F!!%1PB64+Rz!!*'"d<#?g!!!!"zd<#?g!!!!"zd<#?g!!!!"!!$nIBl3nNz!&+BQW.4jJ;ZHdt1dD$@W^$Oa-C4]4'&*Bd:d>!\<'UEb1G]"41G]"41G`QQF(51Mz!")7n+A>Tf0K(cgzzzzzzzzzzzzzzzzzzz!!$kPF^kCOz!"o83!"<aS:/:ii!"o83!9eBD:fIDp!"o83!9eKI;agZd!"o83!9e$/7S*R[!"o83!9ds%6q[L[!"o83!9e`B6V[U]!"o83!9e$87T'3d!"o83!9e0+8l,Kf!"o83!9e!3<Drkt!"o83!9eB<:eUih!"o83!9eBD6;dd`!"o83!9e!878j0d!"o83!9e`B<*'&"!"o83!9eHG;H3\s!"o83!9e3:92Y`i!"o83!9ds)6q%(U!"o83!9e<::.tWf!"o83!9e-=8Q5Zi!"o83!9aDR!)NY<!)*Ah!&FU/!&ag7!!$kQDe&hJz,4GR4-BJ3-!!'kS8:U[?zzz!!%+PG]Woc!!#B)E-ZJ<B4uB06#^dZALnrqDIY:M+>PW)3<9*<!'ittBk@>F9hbU;!!!!)!!.jh!!E9%!!*'"!#bh;!!!!#TE5)r!!!!"!!!%>TE>/s!!!!"!!!!Rzs4[N@!!30%!<E3&!<E3&!WiE)"9S],!WiN-"9Sc2"U5/8"U,&6#71Y?#7(P<"UGJA#RLeE$46tB$OdCM$jd7J$NJi\6NI5i!WiE)"Tni1$3gY<$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$4?gK!"fJ:0`c7r!?qLF&HMtG!WU(<*rl9A"T\W)!<E3$z!!!!"!WrQ/"pYD?$4HmP!4<@<!W`B*!X&T/"U"r.!!.KK!WrE*&Hrdj0gQ!W;.0\RE>10ZOeE%*6F"?A;UOtZ1LbBV#mqFa(`=5<-7:2j.Ps"@2`NfY6UX@47n?3D;cHat='/U/@q9._B4u!oF*)PJGBeCZK7nr5LPUeEP*;,qQC!u,R\HRQV5C/hWN*81['d?O\@K2f_o0O6a2lBFdaQ^rf%8R-g>V&OjQ5OekiqC&o(2MHp@n@XqZ"J6*ru?D!<E3%!<E3%!<<*"!!!!"!WrQ/"pYD?$4HmP!4<C=!W`?*"9Sc3"U"r.!<RHF!<N?8"9fr'"qj4!#@VTc+u4]T'LIqUZ,$_k1K*]W@WKj'(*k`q-1Mcg)&ahL-n-W'2E*TU3^Z;(7Rp!@8lJ\h<``C+>%;)SAnPdkC3+K>G'A1VH@gd&KnbA=M2II[Pa.Q$R$jD;USO``Vl6SpZEppG[^WcW]#)A'`Q#s>ai`&\eCE.%f\,!<j5f=akNM0qo(2MHp@n@XqZ#7L$j-M1!YGMH!'^J^eG-NC01u",nG`Ffa4e4cpM":c88PCn1>L,"M]>S:ok/CblnWoh&#FYmpsZ*f6h'8mIO]^cdki!c&P7/NgtMOeqa+M.%A^H91+Y[F`*5e<*0Mi!INs5)nE7bT"_o(ZnRPP2Nh[.g9G3_gNKo-lLr5u4W\?PoW5p3@jts8l?<$bImu"h-G_]Y9cn@#KZ+/=&hgW]6hUSBAOXXZQb5utFf-?0\bAC!hWk54??CH'+Xo;O,jZG?r;L%q4D\)X+`4lUfe,0a9]im!P8(?-k&mdiO\P%4N?n)n$Q%8b5Fp!n'):A!Ka'XdT$0Jnj:W*cqej&YZfjBR'Fe(>,CGj$GbqP,0%C8O#^@IG;jCJ**k\`QbG[BRlGD?)2bH'P!Mo.J7I.habPKfAp*E`N;/hl%*^`@[$cPM&TPC,dJ*Zp1[)*CitkYc-sl>I+ngHfO/M)V4C(nk#UJIB;1SYM_H:A!sdj,-^>D82D8Dl2B[R=?+S!,173r#XEH9g\0]*Zr/drfuTXdO0tuK)O\?6HlmA+5R1C$_NdeK?,m`.fH'T-XM&0?-thFr#p\uZgaIr8Zpk6)S!%tSk+OlB=:NoQP#<P2]:Wr2f="DrKb/,Hs9gg6Wro\]p?!I/9;=5l-Q5-Z-+3EN[-)A?ml.3+HLm^=5jbW]qG/T`EJmkoT+fW-h,o[rOd)oNn6P2=CTdF(LUlW7b[`':!8PYA<L,<_K!Qd4$>c/lfIC1APF]KP1DaBXi7%4.e$[]KU;Z<[db]32%;q>L"]b>JZ[uV==1hB9*0-'#9;<UJ:9A#k3q:d?OD68Hn^W!\u#+g/bYBLAZRMZD0h>MM%_$IUNI'E$j\(?NWGP4B3u0_qSMQI"n=4?iVB/9ID:Og%=j<7bA@^)R9b3iD:0%hP1do%p#`.@(VkB)$2ELUM*<9Vrk%0LCtK[W9<E)&G$2U_1Ft7L)CcLP2`<EVa0&A%[Y7.ZH'R9if!jdcZr'8(FbLN,5Qqj!5Qqj^kn4j[E2oZab]!RT-B\\/\V2Xfj]Ngj6R/@D<X4^P*C6NEHZ]A=<B7]^iTko40+?10fd<OX->571\j`2]`cCAdG81rWJW:1PC]=AIr!hV7'kr+(nHXkZ[FFl47[\$92t)PF@rNAdP!B&(al$d8WJeVjK9]&kMG6S-Uq)sd036duDVJI9FH,!&U:LOC<@p/JSfQC#Y;FKK?F%2Re)V+ugY6!ZZ<K?7(0+7)'=@8]k\Dn:.<lI(,!Wr,iWL1j>)SHGR+N%)B8=LT_/S.MS/gRl3N%hQ;c.V8'W3Q`G.!XMlL+:j/TbI53XR@&WT$,QBQmLC>2Hr(B/TVD9oN.T8J>?"EJ09*"l#0TalHI&S#^<a]_fm.i]oa^,D@!\!&Aso"6sZ5;O_]!9(CeE]'J*:O.qL]^aPq7!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!9X82Hrf`t_7p8jN4`^a_VJg+@><Jio$8ff66IN^iE5Y9_ObP^)u^1+i/PZ._i7WSn4hD",-?@27R,t#BRf^t+8R0RpMUDk=_W=&e+ESsdPrA(as;]Y:a2Wf(]Y&2q=ZHV`7_U5ic=r$.QD0fGZ/h[C86u`hcVI5h$dMe.ZPt3a!^@8p4Mj1a/pu^o>;/G>?t>d$gS2=!TO]]X;OT1;mhAc,928sSepAkmHsDh_7h>/nA^aPm7159;`$;e>J+sodOE!EP"BTu,Ba&Hj!1#e>5>B$$2%e=DnL"f)d(A#e00Z]fJ`p[;H+^QO9lrs4U!t2'u\a@:0j+3`C3kH3h4`KQV)8[<i4s.h<b+-e^_)73f1j*lHKbGrX't@dnnS'ZIZZ1X&rTKiEkk+:*RgWbb0T>h\eV.f<K]lpo!'=L)pVaa8RC"/Z5>@P&12aXr75u`&!-"e/X%"8HYFP^\B3GKp;T;"RRl)[76bF?A([#?^V!d+CG^V%L,FN%maIXm=#!7-AgZ1qYJZ*oR^iK0cWR!R07Rl(qS,5:Cg&4+[/XqAD4AID)@]qrr>3(QT;sO2gZ=trX(aFE9GF>F/p&%"PlHP*o`C_*^/GQrr<N$:](TX]t<5,Xf[Z$T+,"-gS@]LK4mS@JNtOs,iF!3:ZGa^q\eWZ>X,Sc`!2,pJPDZd&_[g.*_Mp!"]P;n!"M'tkJgQ_]I#EfU&Cf(ou>P\KNBInc/%u6?YB;#F]1r&Ij:cYQi%O>iI8JC6)8:f):\;WXs?tNfbulGN0B4BJdS]\!<#"2V>PB/d@kppn8*P-f<i`%`1HcV+Lec4$V8G/a^`*o)tVB8*UCh^i1j<g:[n*DeJcjlEuqVr8bNV0)CHhPkXm;EYc5BUJ,)%,&,uX^Iae;s8M2N07hBYm:P@!^pknUD<s]4TKgc.eNBJ8!es=eTm$jO)Umo&TTCDC>"b4oYeUR'<.eKoq5IAaf5!9jc*<t*_a&0-u8TA6d(FCnW^,Al5-m_1)#UFE2-`m)]@:c;551&s#3mou1Mb1Ai`=`>SrS!iqgll)/r"=T%5PFU:Q*$!<$qAh:0uPuLb`FR;Hh6p5[uB>%P9$"5)iTe$SgnIfO0VUDk)4F];Jk*iWF*,DocW:=H_-Yqch=R3#Jf.r0+M`_(V5X+/0\#,Au_RRal'e9!#(!8!BbF^MW$-Oi1k`$P3!>NiV'Mj7DF*nF%%<%oa479jstZ9#OS@`Ho^`Xh[[:Pi![:3C)3Tshii9F._a`X'+qcq!?'g'jE@^Wq"OYiplFE1_`Q0JlJD[kdNZAf0Js7(VjKkP_u,&%Qt*LRGB>3b?8iO;Q!>@X'.bJK(s8,lUp/:1k)\/;DUmLhb=&rdC/qT`QJF*=T>qJ%SeTYgB7$h<)H:eC2B)7F['=t#gOhOJL6Hd=L$'ZuaMiDmlne1jZtO<j#rdV3%79(S!*>J2DW6ltm3"-\m&B%qP]f%crr=%1I08C<r0Y:_ra6Ybrf4Ri^[P"Eq')9*rJ`W5!9lAKD=+ZGhhs7;A8A2OgCMTXJp'jT;i5GjX/)6[D1+p"8u,be7Yci(4q8+X2ak.)o^-&]U\cU#CRCr*Ym)r(=3O&'mdg+2WS<TH#Eh4L!;?0<jm^U8Y6F]a(`$3%i;6-b`rXD*X5KSbmB&#]J'(-c&,Ps[rr>WeW;cj74'QM#!0=l)lu-9'@@DG9Q73Vj\soJu&_mplH("VW\@rm+T`l9*35lT[[_1+l.<g3t;,+M+HC%/"'S!r16#VM3TK)!?\BjfNA,&(ST>BD(r%?hSn:T#E']p@89=,!V%KJIr#oFe:#UCLj+E]Hmg"]`=T098oDXj+N#=).JN"mkiN,aaNVu@"XU)d1Q[]t4ba)to)!TAKCTuZ'rj^2@b'u]o$'4A%(ls+O0nS4ft&uO[Q_j]l=GJ;e"-W2`l]A2a;B:J@BpV.\3+hrRZ22'ML:hJ4Te0RS=6g$\$?rc;fbIIKG389C4UQEtijWp-6p$.&!f-Mg2DuTeb&+M%H^8Lu2d^Q(&J)qrA+8+oKo[bC:U;]6-%HV_;@iOPBdONH8[5o13n;jR#rmdA8!!hKQQ[l4;-0b9F`R*/ko\lXjLkqnd&*NBBPd$(!_dGA.k]8uHTH=a3oIks-rr<RAddABM?^&]gm77i0j@^.?4iod@:6gV3FoMH`;##87!+/WRkkH[ArOBW'gpMY.qR$8&dHOu'G?YZ:Tu<1po$_Q:4lmC5Qa+2fT3K8oVtP%O[>LGj9Zm<nIQL3m&&U;t%fZOf(t=K-)F>b,[5<HnAcsSRStM@o#GN.(^'B%8n?9m%>uL:3)K"TAl$$nVMoAM'7KfKGUuOO@+S>E*rl`(IDr)6/!3fB$!9d-`62pofgn#1UGd?5P?Sh(-N)OrFNO"N'e)%bXUGC*blBr[pX^tBiRWTU>MGDQs#sp-!bBl1\[sa-mUq%.cT$?fCj0+19"6anhmtpB`m[!_E>K729WGjOoTB78)5j=f%5j=Fn81'5V'Y&k+,`3HY(s!pG^2X)PJre"jn99V]1'$^@bX)ub!\on"`-u10LX?&$j9oW#!+)r1!9bW@O"AQGGciO?0GA6T:lQ8328%rs/&&\[$]LRRj4_JPn1PZ.hu3cJVi(-h$q&s4<q#oHnk3W+'#tiOOc$DD,b/BbB9G!23`j&Ib[7X2XgGjMJ&GR%/^^DPk2\rU-nKqPh`*d*Jb`@X(M4Q8%"89\QW@'sM4BcnJt8-9c*OnDl7.s[Bgpb<^5r9o"VpfLH)S]!XEZC"ZaY+qh((u[QgRfa80.5akRDklNd`AN5N2?ek4k(Bl6WgYiCP8@Fn6N"pt2j1NQ&@8EX"NL!(c\,paA"rXM4liY3!,^Q7[C`'SSh`#!$aWgGg)I$KchP+8IYK"TJJRY)iS_Uh77X]L0V_%.c#.0!oUS_pMIm/k$4TeXTQPV"NUDHKbo\LGEc@7oAdQp>+/G-@!PZ_B'He;m'@ge]OX\NuJ?L/V>U)E1o`mai>7C>PP])D1"><>N4Cu"im?P)R\[jm(IaTOi8!o3s.4\0[D]q*Aa4:h>@Jc\$YoRi<ZQ&dPX3+Z#[+B:g'G\@tEF?,bF(\?6/nqg=o@!@/NR*RbB]`/%nKlm!t<Irr<:<m?,F(GcZB1@5+&W5M%,0pt;j#fgaKOaj"B2m3d@br/`j7,d47*m!mrg?Opb]N\*W63kQ$1@S*>\.7t+V\Jb>2g@]rPrWpo#*^@V:X_h90>:$jRaH3luNK'E/Y3%:8!Pumo`Gm!.`MK]Wm+LA)Xt?E2i0)AV*RHO#c.kt&8a(?0%$&P%HLid)1H54FT2$rj3.uAQ!+3a'\aL/Mr];'O``J0Hd_a0>$%"O)bt5s@W4-nlIIHA>o7Lbhl#U1srX([D'Y&:lpj&r4&7QlI8`G_sHBeWnl'#C3_9^k/_4MPAGAZ7GD[L4tIF[\))d-d8,Xu<3+]Gk4ntR3%A%d"lZP6SB?N@_iFElbHharg(0E;-?r`TtqXh6Q?o3O7_dj"elJrs7H/Kms4,>KB$4O^0!\@+VXSkjb,Y%jA[)!/-qb\_`TC=C/PUBs4aN,5NZm3LG0>$fCeOE4B^.rTcV4ceX$m1\E=J@7A!G`iH8]?C0Q!+W7=<A)+-QZC"I>`^b`,k)9R1O]K+dd_^.eSZs\Itmg-NLdE[jOGk')?BR58!/b8aZ(/#E]_m@Ib#:cpV4,&_eV?WFI!eWYXr;d""U@c+KGU\"EB'$9OH[\BpLR?HA(Su(@\];b2!XD&kVp"9mm4OO3[?'-H7^?.Tfq$iuUVlh!YCngtTJam'c;n[-&p">nQ&04T3".)>HS;[ltbZ]JlhTVTre.H`6X()0In^2]^*C"D!)4N/hW0&,uWJItiD.nO9X92.$l/)F;')@=n(/j,t^33!)DP-jd]FJd-M9afK9]pa@Y"l?=rW)rQaQX4b;`>GHXVEXm%l1kn`8_8]ZkDt]dtorS('eb"^k08AlQ\[9F_`m[Q.:G?At43VA]WD3XW-'!8SJBg.S!#(^9Ge>A=*(MQFW@Tm$)(o\]Wj_V&f'`7Y``8OO;SU<M$faasmfn.JnDo$@nSu($Y%9=jg"IQ_B5fVGOoPK),k7#HO:REP!5lji(&n8%hc9[V^ppDBr"MF0D-Oe08thC8DhG%M&\?Gpk?g\oeeV'?Heg:?i\o%i,Y$\7)[^C+DVgc$)"b#<`8`hP2rZrK%g.`M)P.O>\*fMO-TH24gK(c:?dR33P+,%sa3XbcnF>rMrrCG*eN`OU3p?PYrnP6tIO"Wnf>4qB*i#Oe?d>n.bA^?]UlgZP)3j5cM#_K\-^$!Grr@Xi=P8`Cpm4koZ2L?Q_\&MKhln7cF4V9Tig9A]Yd0&E^V`3(.nJ6:od!,+;urOjjpe#FHu<bHACo)ao?K4k_Xog>XtgZDV&RkV;-HSiZhW!ErH;Q2$?]?+2UA3JU5JoRl9'"Yh"Y=;mtmYDmA'/_R.o39AuN1:=i)s?Z$C5HjcAD/=<40"1QH]B<f-]\r-6Z^HX/R-rL1,UM='5'jde!k@1j:lh6Y3bF,lYGoZ\-@\X*Z`/*@X'*!S<GC6`9Gbp^GD>drg<P0p=u8t0k`:<*V/1ZD3KYDIRBf!48MKlVEMh+A%UEH9''N9>18Z7@DcQN[!-)9%"%i*BFEa6]5SD\;2qHlfrPm'TK[,Zbc4nsJJDca$+'NEBSiS=pf**=d/`m1f.5'ua\I@;#8d`ta>LEN@7j^3+-;)^sFk92-&Mmnf9-daqHGL%0fT:WNJ8g1*XYphOC/%oLd&[04"&BeAHiPmj_)8J)Rl)p'D>\K1VRp:g<?ip4qD_o&&VnD9"EX53#$NJ^t2Vcu"%<@qd<\4$RW/BU#'&?gJU\<d:YphXJ\\@L1mMLpJMN+:$Jh5$d1[sJ%B[_7sT]=lF<LUqWjOl.5j8^q-&>[$@bd*E:a.-hMH&&<g(/,Lf@"3/%lq!7G`=RcoVD_19&^6*:#DBUa1jfTWUb@C:dg`3I^"`oW]r<5W<"tq+:iph7CmVP'2D(Rp:_j=`V6JN5gp,k;-oC-[Ur+5BL8@@rRLMo%!@FpUa'pK.`W+_u'9!1oJ&2VdtlWN,SoFfo+!RRsG>WdHZ[9"6k#dh)G^4WUArN:S\pnQk._T9AOi;Wd'YH7D1Y9SX5"Cbc<,\9=a!Q;U\rpDl"c>d2#e>\brR&hqu9%]SOO!7s&me4+jg3\*Z\J69`RbaQ<i,@?lj#sSu[*(FYB=lts+L7"Qe88^*<4Gp/6\)Eqj:6-"c?aT7?eJ)fh\3Xgn[$.u+$Lfl8pq=(7bUhN[CLj]B6bL7D+>P&.S'5h)'i_*I0&;$2I.9=g2<$88rm\a_[E2K$<7.h1#%T#:G:Z(_H$)jo.5:TX?EBs3'o&eQH?S%1U[(kpNt\T.:"qqf_J=^g2Fsfg#)Lkf7#1DGN!trM"LXcAb%.!#p`?QZ:MlT@>o*,KmmIQk8eRepoXEYI!#/*i*4N^[bnEOX(hO2@nA!_QSYjGFaoZM8cd'E8\c5?O0!#rWph>e;oE,6\W#c]X3,<Zq&o\;M=Dl=\ZGL1^CYKnWCo^+J&?bjhBhYMm%aR\$L:Tuo/0P;p$d<AIUXUqcB(FKeU`r<*"i`;?=3R@C4@-!-Be9dPMm8#3`X1spXd"-W3Y(^!KK!J5fnj%&Z-7`P&l2qqLXUtC2f.\j01M%4aBq-3.!KFMro_fXP6Nn)`EuY=mB(peMQt`IIWYSHu!g#G%a&l[d_9&RSqcCI7YP.":G@2gSF_H6P)/=&'V\,1;C9,_]O\\hQu1%ME_UC)>-X^$=i8PgHoM78<G0W`,"s(goMG83:2kmJYJnQ_,r6`?&c]nXHLP&p:")8-180YkrAA"mH,cf1tQg2aa\-QNi(Km&)!.D=c-WuBPs5*A#Wf`&i88elW_-.cbb/NGQYjpmu"c#Us5gmlh=5CXKIc1Pu8bKhW`QL1s@kd&'LIC7Xa#J;S_dn17iDS0[)9#`6Nt$,&r8M>h:O!]!^!]5uW0ddW_tfn*I79*uT<-j4D4T:LEVAjfP?1d]Kq4p?`hum^[O?)_`5I;B$jc)='bei%GuJ!5j9<GgUmpHJ1ZhBb$rIlsNX@A;#R^2M8Z@gRS2ZNbdi..FR.e*A"Z/K2lL+6Fs=kQYfJqjaLP/]Cc\F\Phe^I/EePp]nff/GOqgrr>pca+j%?#bf`nNo@)lg/.nB@:3Ug@6k7`,ie!)9'j</I03aE0C8]=X6I>>dOoI@I-YD\er[8e'j8ng#b[B4ahZg9H37KI7<I/?>W$/^5A8[#ifpnGD%99%pXF)LI,8Lorl8=kpo/PsX'Z-WYMk/'7[KlQq%.:BY40VW-L?8e3Wjm=b@_[m%.XTUO2#,lLAJZCY-n90%/`]-nFPJWdTkG-aV>\RiZn8aPtt\`GI@\Uq?su^=2dtfn)4erY7o+>%:&1EIJ(AtCQhB$8Chqa!6h_nJ8b`DN8l95-G6G+KcB"9(b*j7q9cKSdXK<7CO<@?FL"J@m^6o=9W@oG>4t-krMG#FBcdOhddA[#.5&:ko15$K8tfgM<!"%JgZ9]Cc8kRbpF_7-dB*EhrK]SG!8f!5GJbN,8&4R&l^%D&pH%0./`[DMHBm8[$a;W1ei8bqaQQA063sc2kH/1.gb"H*ES/K8=u!q3^ESXsc;cI;S_KC:GAdE\IumR*i7i"u$M]84f>\mKr$(q7j"%kMp`98u-2s`d*7cgFL-Ve[bT0;+&-m]Lp$H+)f8b4`p^cBAL-HV>DrV:3gHM%,9[BQ\P6Q56->?"^``/lZ*9/ED7npMB.*Zg<cRa;ib+")V[o+YJP47;*V4F-!ddPF'Wu4N,Z/jdZ4skZ)rM?k_:PQ;BZhC5n#1O9/RGjNb<&0H]8;ND3c>q-KduiP7^M5ufhC4*N<RAAbU1ohV\!ebpTX\8k#+:iI!K!@D%E*-/[mOKp79heieYA*"mOiX_@\B^2\AgY9=1+e;QL=56e[*qBmdAcSHmR3ZoH/d9):8%\G)GS._tHo3`5;a(8.f!#d"3e1m7InJrrBB,m2+cC*U'+'DYur$pk%Mb8>`f(Q/a;M^2O-Ee[@NI</)CNj,=oQb)5i_Sem,qKu1]lGu:VrBu4R2eYC<fH98=qg(c)ba][?<aaY**3dc2IjkuVhL";m&^8k^#3MI/1/ZpC9,`<cIFD;WS7EZ?p!W(EWp`JG&SJUYQ@IS'l4@.sf:eaY^:ct]bR7UI"AiCibaN=V+Y=5BI4Z:2]dr%!j>1"rSDW#bW@$G55NIb,2*Phl>`jrDC':p-^>8rXA4C)]drKk89`]TT)`Mfh?^#*Vh.+>M>]<gYKqZ_:;g.+j^j42tu"j';o;6_3@Z7%*X!k=kRIK["PH2DICh@\1`;&6\GP?g-@Q+5e^=A$Li$NS=VBu)ola+<P8hsaEKJ_*tD>f!OeP1^kt>Bhg[.2_\Tn?ZWi8b]C*i7I>+n@RV5V`q`OFM>B%RNiBWeLhV=MDKia![9&<##6u/3$_SC;W'*39]$.WQ=!Do)AQa[;cW!YnUnS+Mb,O5QF>8`a\dH-g=GjT5MA'3*]3C'm7$O1`*+OC05e/o>FS!&HO[SL:jH,S=7[C?-53#@)<VmRYAs)]M^O@/-`VE7$._&b2!OCj7i;S=2F'h,h-)X:l1c6R%t_a[.s!_!C0]1_Vn/X7DnOml-Jrn)rr@\d&AC:+bZ\VPnETK9I_XBbC+XH!M!\eZYuO/J@n'U"pL=>Qnot2M&T3%WIb4QPnG`KDDZ1+%BJt0acf\V>>=tq/85m`VRRBsP=N1m\Oq1KA5/O&.6iJ7c,$B;6b.3L'?rLFEjat-E\WhBfk1stN)>b4f="OrTIr7INps[8%hgl``4rCu_<o6`aNo@)lg//0"[jkXD\thgYESt[o,/*GEJkMXik1UQnaTJOOj!:T*VkUoG#EdBLk.&WWADFFpQWdO46]kU'C@5c.Pah)c-gVH'Ii*D`_0Ys&]>Ji]A'_3U_]A@R(4D$o+^:*136j3K3'8*dg;h#.0_%*@hhJ_7LV,KkHZ*]#ip(l(%#G5Xi-`U9g`'7R>6>4Xi7GY>?;u/2#p'hZOo&:.3&nWh0)963Ssm'*6@G$jI"?q8BVLC]"&P_L-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ii[!U5nkC5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Tg$Z~>endstream
+endobj
+% 'F2': class PDFType1Font
+4 0 obj
+% Font Helvetica-Bold
+<< /BaseFont /Helvetica-Bold
+ /Encoding /WinAnsiEncoding
+ /Name /F2
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER1': class PDFDictionary
+5 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 55
+ 626.125
+ 145.135
+ 637.375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER2': class LinkAnnotation
+6 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 564.9375
+ 117.5275
+ 576.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER3': class LinkAnnotation
+7 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 55
+ 456.5763
+ 0 ]
+ /Rect [ 70
+ 553.6875
+ 114.1825
+ 564.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER4': class LinkAnnotation
+8 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 613.3887
+ 0 ]
+ /Rect [ 70
+ 542.4375
+ 107.935
+ 553.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER5': class LinkAnnotation
+9 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 530.11
+ 0 ]
+ /Rect [ 85
+ 529.1875
+ 190.045
+ 540.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER6': class LinkAnnotation
+10 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 420.985
+ 0 ]
+ /Rect [ 85
+ 517.9375
+ 172.12
+ 529.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER7': class LinkAnnotation
+11 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 344.6775
+ 0 ]
+ /Rect [ 100
+ 504.6875
+ 161.6875
+ 515.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER8': class LinkAnnotation
+12 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 55
+ 291.9275
+ 0 ]
+ /Rect [ 100
+ 493.4375
+ 178.3675
+ 504.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER9': class LinkAnnotation
+13 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 742.865
+ 0 ]
+ /Rect [ 100
+ 482.1875
+ 184.6225
+ 493.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER10': class LinkAnnotation
+14 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 678.865
+ 0 ]
+ /Rect [ 115
+ 468.9375
+ 221.725
+ 480.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER11': class LinkAnnotation
+15 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 246.615
+ 0 ]
+ /Rect [ 115
+ 457.6875
+ 195.46
+ 468.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER12': class LinkAnnotation
+16 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 111 0 R
+ /XYZ
+ 55
+ 160.115
+ 0 ]
+ /Rect [ 115
+ 446.4375
+ 206.7175
+ 457.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER13': class LinkAnnotation
+17 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 722.115
+ 0 ]
+ /Rect [ 115
+ 435.1875
+ 200.47
+ 446.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER14': class LinkAnnotation
+18 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 657.2975
+ 0 ]
+ /Rect [ 85
+ 421.9375
+ 180.0325
+ 433.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER15': class LinkAnnotation
+19 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 306.9225
+ 0 ]
+ /Rect [ 85
+ 410.6875
+ 160.0225
+ 421.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER16': class LinkAnnotation
+20 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 113 0 R
+ /XYZ
+ 55
+ 219.365
+ 0 ]
+ /Rect [ 100
+ 397.4375
+ 197.53
+ 408.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER17': class LinkAnnotation
+21 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 117 0 R
+ /XYZ
+ 55
+ 614.615
+ 0 ]
+ /Rect [ 100
+ 386.1875
+ 193.36
+ 397.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER18': class LinkAnnotation
+22 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 117 0 R
+ /XYZ
+ 55
+ 485.7975
+ 0 ]
+ /Rect [ 85
+ 372.9375
+ 194.2075
+ 384.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER19': class LinkAnnotation
+23 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 117 0 R
+ /XYZ
+ 55
+ 297.4225
+ 0 ]
+ /Rect [ 85
+ 361.6875
+ 157.5325
+ 372.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER20': class LinkAnnotation
+24 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 548.2975
+ 0 ]
+ /Rect [ 85
+ 350.4375
+ 196.285
+ 361.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER21': class LinkAnnotation
+25 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 450.4225
+ 0 ]
+ /Rect [ 85
+ 339.1875
+ 191.7025
+ 350.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER22': class LinkAnnotation
+26 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 385.365
+ 0 ]
+ /Rect [ 100
+ 325.9375
+ 147.94
+ 337.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER23': class LinkAnnotation
+27 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 266.865
+ 0 ]
+ /Rect [ 100
+ 314.6875
+ 161.695
+ 325.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER24': class LinkAnnotation
+28 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 125 0 R
+ /XYZ
+ 55
+ 159.615
+ 0 ]
+ /Rect [ 100
+ 303.4375
+ 144.61
+ 314.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER25': class LinkAnnotation
+29 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 645.115
+ 0 ]
+ /Rect [ 100
+ 292.1875
+ 143.3575
+ 303.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER26': class LinkAnnotation
+30 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 592.365
+ 0 ]
+ /Rect [ 100
+ 280.9375
+ 174.1975
+ 292.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER27': class LinkAnnotation
+31 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 418.1388
+ 0 ]
+ /Rect [ 70
+ 267.6875
+ 189.625
+ 278.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER28': class LinkAnnotation
+32 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 133 0 R
+ /XYZ
+ 55
+ 200.2013
+ 0 ]
+ /Rect [ 70
+ 256.4375
+ 197.1325
+ 267.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER29': class LinkAnnotation
+33 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 134 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 245.1875
+ 159.6025
+ 256.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER30': class LinkAnnotation
+34 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 134 0 R
+ /XYZ
+ 55
+ 675.235
+ 0 ]
+ /Rect [ 85
+ 231.9375
+ 147.5275
+ 243.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER31': class LinkAnnotation
+35 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 698.7975
+ 0 ]
+ /Rect [ 85
+ 220.6875
+ 155.035
+ 231.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER32': class LinkAnnotation
+36 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 480.1725
+ 0 ]
+ /Rect [ 85
+ 209.4375
+ 147.1225
+ 220.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER33': class LinkAnnotation
+37 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 141 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 196.1875
+ 174.1975
+ 207.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER34': class LinkAnnotation
+38 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 141 0 R
+ /XYZ
+ 55
+ 571.3262
+ 0 ]
+ /Rect [ 70
+ 184.9375
+ 155.8525
+ 196.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER35': class LinkAnnotation
+39 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 141 0 R
+ /XYZ
+ 55
+ 320.2975
+ 0 ]
+ /Rect [ 85
+ 171.6875
+ 124.18
+ 182.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER36': class LinkAnnotation
+40 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 607.115
+ 0 ]
+ /Rect [ 100
+ 158.4375
+ 244.645
+ 169.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER37': class LinkAnnotation
+41 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 511.115
+ 0 ]
+ /Rect [ 100
+ 147.1875
+ 171.685
+ 158.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER38': class LinkAnnotation
+42 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 469.615
+ 0 ]
+ /Rect [ 100
+ 135.9375
+ 205.0525
+ 147.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER39': class LinkAnnotation
+43 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 404.7975
+ 0 ]
+ /Rect [ 85
+ 122.6875
+ 131.695
+ 133.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER40': class LinkAnnotation
+44 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 253.9225
+ 0 ]
+ /Rect [ 85
+ 111.4375
+ 171.7075
+ 122.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER41': class LinkAnnotation
+45 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 146 0 R
+ /XYZ
+ 55
+ 165.2975
+ 0 ]
+ /Rect [ 85
+ 100.1875
+ 162.1225
+ 111.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER42': class LinkAnnotation
+46 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 710.0475
+ 0 ]
+ /Rect [ 85
+ 88.9375
+ 161.29
+ 100.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page1': class PDFPage
+47 0 obj
+% Page dictionary
+<< /Annots [ 5 0 R
+ 6 0 R
+ 7 0 R
+ 8 0 R
+ 9 0 R
+ 10 0 R
+ 11 0 R
+ 12 0 R
+ 13 0 R
+ 14 0 R
+ 15 0 R
+ 16 0 R
+ 17 0 R
+ 18 0 R
+ 19 0 R
+ 20 0 R
+ 21 0 R
+ 22 0 R
+ 23 0 R
+ 24 0 R
+ 25 0 R
+ 26 0 R
+ 27 0 R
+ 28 0 R
+ 29 0 R
+ 30 0 R
+ 31 0 R
+ 32 0 R
+ 33 0 R
+ 34 0 R
+ 35 0 R
+ 36 0 R
+ 37 0 R
+ 38 0 R
+ 39 0 R
+ 40 0 R
+ 41 0 R
+ 42 0 R
+ 43 0 R
+ 44 0 R
+ 45 0 R
+ 46 0 R ]
+ /Contents 237 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ]
+ /XObject << /FormXob.a31102908a592e8f94c7b4e032ffcc37 3 0 R >> >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER43': class LinkAnnotation
+48 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 583.6725
+ 0 ]
+ /Rect [ 85
+ 730.6775
+ 115.015
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER44': class LinkAnnotation
+49 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 419.5475
+ 0 ]
+ /Rect [ 85
+ 719.4275
+ 152.53
+ 730.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER45': class LinkAnnotation
+50 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 310.4225
+ 0 ]
+ /Rect [ 85
+ 708.1775
+ 185.86
+ 719.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER46': class LinkAnnotation
+51 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 148 0 R
+ /XYZ
+ 55
+ 169.2975
+ 0 ]
+ /Rect [ 85
+ 696.9275
+ 126.265
+ 708.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER47': class LinkAnnotation
+52 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 388.5475
+ 0 ]
+ /Rect [ 85
+ 685.6775
+ 152.11
+ 696.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER48': class LinkAnnotation
+53 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 322.6725
+ 0 ]
+ /Rect [ 85
+ 674.4275
+ 135.4375
+ 685.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER49': class LinkAnnotation
+54 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 256.7975
+ 0 ]
+ /Rect [ 85
+ 663.1775
+ 119.605
+ 674.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER50': class LinkAnnotation
+55 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 202.1725
+ 0 ]
+ /Rect [ 85
+ 651.9275
+ 138.7825
+ 663.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER51': class LinkAnnotation
+56 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 152 0 R
+ /XYZ
+ 55
+ 104.2975
+ 0 ]
+ /Rect [ 85
+ 640.6775
+ 173.7925
+ 651.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER52': class LinkAnnotation
+57 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 612.2975
+ 0 ]
+ /Rect [ 85
+ 629.4275
+ 195.0625
+ 640.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER53': class LinkAnnotation
+58 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 343.1725
+ 0 ]
+ /Rect [ 85
+ 618.1775
+ 135.4525
+ 629.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER54': class LinkAnnotation
+59 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 222.3888
+ 0 ]
+ /Rect [ 70
+ 604.9275
+ 166.2775
+ 616.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER55': class LinkAnnotation
+60 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 632.8888
+ 0 ]
+ /Rect [ 70
+ 593.6775
+ 177.115
+ 604.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER56': class LinkAnnotation
+61 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 538.36
+ 0 ]
+ /Rect [ 85
+ 580.4275
+ 144.6025
+ 591.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER57': class LinkAnnotation
+62 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 461.235
+ 0 ]
+ /Rect [ 85
+ 569.1775
+ 190.465
+ 580.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER58': class LinkAnnotation
+63 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 384.11
+ 0 ]
+ /Rect [ 85
+ 557.9275
+ 182.5225
+ 569.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER59': class LinkAnnotation
+64 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 159 0 R
+ /XYZ
+ 55
+ 318.235
+ 0 ]
+ /Rect [ 85
+ 546.6775
+ 216.73
+ 557.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER60': class LinkAnnotation
+65 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 162 0 R
+ /XYZ
+ 55
+ 591.1387
+ 0 ]
+ /Rect [ 70
+ 533.4275
+ 161.2825
+ 544.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER61': class LinkAnnotation
+66 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 162 0 R
+ /XYZ
+ 55
+ 452.9513
+ 0 ]
+ /Rect [ 70
+ 522.1775
+ 148.375
+ 533.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER62': class LinkAnnotation
+67 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 162 0 R
+ /XYZ
+ 55
+ 226.0138
+ 0 ]
+ /Rect [ 70
+ 510.9275
+ 119.605
+ 522.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER63': class LinkAnnotation
+68 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 163 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 499.6775
+ 200.065
+ 510.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page2': class PDFPage
+69 0 obj
+% Page dictionary
+<< /Annots [ 48 0 R
+ 49 0 R
+ 50 0 R
+ 51 0 R
+ 52 0 R
+ 53 0 R
+ 54 0 R
+ 55 0 R
+ 56 0 R
+ 57 0 R
+ 58 0 R
+ 59 0 R
+ 60 0 R
+ 61 0 R
+ 62 0 R
+ 63 0 R
+ 64 0 R
+ 65 0 R
+ 66 0 R
+ 67 0 R
+ 68 0 R ]
+ /Contents 238 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER64': class LinkAnnotation
+70 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 417.365
+ 0 ]
+ /Rect [ 125.8675
+ 663.865
+ 170.05
+ 675.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER65': class LinkAnnotation
+71 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 404.115
+ 0 ]
+ /Rect [ 326.365
+ 565.865
+ 370.5475
+ 577.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER66': class LinkAnnotation
+72 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 390.865
+ 0 ]
+ /Rect [ 309.6925
+ 522.615
+ 353.875
+ 533.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER67': class PDFDictionary
+73 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.ietf.org/rfc/rfc2119.txt) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 189.625
+ 405.1775
+ 297.1675
+ 416.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER68': class PDFDictionary
+74 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 205.45
+ 391.9275
+ 369.6775
+ 403.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER69': class PDFDictionary
+75 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.965
+ 378.6775
+ 254.6725
+ 389.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER70': class PDFDictionary
+76 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/packages.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.2325
+ 365.4275
+ 363.4825
+ 376.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER71': class PDFDictionary
+77 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/Manifest.permission.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 172.9525
+ 352.1775
+ 413.8825
+ 363.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER72': class PDFDictionary
+78 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/os/Build.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.96
+ 338.9275
+ 358.885
+ 350.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER73': class PDFDictionary
+79 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/2.2/versions.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 186.715
+ 325.6775
+ 373.45
+ 336.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER74': class PDFDictionary
+80 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/webkit/WebView.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 171.7
+ 312.4275
+ 400.96
+ 323.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER75': class PDFDictionary
+81 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.whatwg.org/specs/web-apps/current-work/multipage/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 95.005
+ 299.1775
+ 307.1575
+ 310.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER76': class PDFDictionary
+82 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/widget_design.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.5275
+ 272.6775
+ 374.23
+ 283.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER77': class PDFDictionary
+83 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/ui/notifiers/notifications.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.94
+ 259.4275
+ 346.2925
+ 270.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER78': class PDFDictionary
+84 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/android/reference/available-resources.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 148.705
+ 246.1775
+ 368.8
+ 257.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER79': class PDFDictionary
+85 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/icon_design.html#statusbarstructure) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 162.8875
+ 232.9275
+ 477.1975
+ 244.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER80': class PDFDictionary
+86 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/app/SearchManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.535
+ 219.6775
+ 371.7325
+ 230.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER81': class PDFDictionary
+87 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/widget/Toast.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 96.6025
+ 206.4275
+ 313.3675
+ 217.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER82': class PDFDictionary
+88 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/resources/articles/live-wallpapers.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 127.4425
+ 193.1775
+ 351.265
+ 204.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER83': class PDFDictionary
+89 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/p/apps-for-android) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.955
+ 179.9275
+ 269.1925
+ 191.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER84': class PDFDictionary
+90 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 245.845
+ 166.6775
+ 453.865
+ 177.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER85': class PDFDictionary
+91 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/fundamentals.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 164.1325
+ 153.4275
+ 364.645
+ 164.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER86': class PDFDictionary
+92 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/manifest/manifest-intro.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 117.8575
+ 140.1775
+ 349.2025
+ 151.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER87': class PDFDictionary
+93 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/monkey.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 138.7075
+ 126.9275
+ 355.06
+ 138.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER88': class PDFDictionary
+94 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/pm/PackageManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 179.965
+ 113.6775
+ 452.1775
+ 124.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER89': class PDFDictionary
+95 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/screens_support.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.8825
+ 100.4275
+ 389.23
+ 111.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER90': class PDFDictionary
+96 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/res/Configuration.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.9825
+ 87.1775
+ 443.02
+ 98.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page3': class PDFPage
+97 0 obj
+% Page dictionary
+<< /Annots [ 70 0 R
+ 71 0 R
+ 72 0 R
+ 73 0 R
+ 74 0 R
+ 75 0 R
+ 76 0 R
+ 77 0 R
+ 78 0 R
+ 79 0 R
+ 80 0 R
+ 81 0 R
+ 82 0 R
+ 83 0 R
+ 84 0 R
+ 85 0 R
+ 86 0 R
+ 87 0 R
+ 88 0 R
+ 89 0 R
+ 90 0 R
+ 91 0 R
+ 92 0 R
+ 93 0 R
+ 94 0 R
+ 95 0 R
+ 96 0 R ]
+ /Contents 239 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER91': class PDFDictionary
+98 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/util/DisplayMetrics.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.6125
+ 730.6775
+ 396.28
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER92': class PDFDictionary
+99 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/Camera.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.2075
+ 717.4275
+ 395.47
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER93': class PDFDictionary
+100 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/SensorEvent.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.0525
+ 704.1775
+ 407.5825
+ 715.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER94': class PDFDictionary
+101 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/security/security.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 220.3975
+ 690.9275
+ 429.6475
+ 702.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER95': class PDFDictionary
+102 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/bluetooth/package-summary.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 119.9575
+ 677.6775
+ 388.825
+ 688.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER96': class LinkAnnotation
+103 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 377.615
+ 0 ]
+ /Rect [ 460.615
+ 462.365
+ 504.7975
+ 473.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER97': class LinkAnnotation
+104 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 364.365
+ 0 ]
+ /Rect [ 470.995
+ 311.74
+ 515.1775
+ 322.99 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F3': class PDFType1Font
+105 0 obj
+% Font Courier
+<< /BaseFont /Courier
+ /Encoding /WinAnsiEncoding
+ /Name /F3
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER98': class LinkAnnotation
+106 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 351.115
+ 0 ]
+ /Rect [ 336.2725
+ 258.99
+ 380.455
+ 270.24 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F4': class PDFType1Font
+107 0 obj
+% Font Times-Roman
+<< /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Name /F4
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER99': class LinkAnnotation
+108 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 337.865
+ 0 ]
+ /Rect [ 350.19
+ 182.99
+ 394.3725
+ 194.24 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page4': class PDFPage
+109 0 obj
+% Page dictionary
+<< /Annots [ 98 0 R
+ 99 0 R
+ 100 0 R
+ 101 0 R
+ 102 0 R
+ 103 0 R
+ 104 0 R
+ 106 0 R
+ 108 0 R ]
+ /Contents 240 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page5': class PDFPage
+110 0 obj
+% Page dictionary
+<< /Contents 241 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page6': class PDFPage
+111 0 obj
+% Page dictionary
+<< /Contents 242 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER100': class LinkAnnotation
+112 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 324.615
+ 0 ]
+ /Rect [ 381.61
+ 261.6775
+ 425.7925
+ 272.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page7': class PDFPage
+113 0 obj
+% Page dictionary
+<< /Annots [ 112 0 R ]
+ /Contents 243 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER101': class LinkAnnotation
+114 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 311.365
+ 0 ]
+ /Rect [ 447.265
+ 645.6775
+ 491.4475
+ 656.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER102': class LinkAnnotation
+115 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 311.365
+ 0 ]
+ /Rect [ 160.4575
+ 506.4275
+ 204.64
+ 517.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER103': class LinkAnnotation
+116 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 390.865
+ 0 ]
+ /Rect [ 125.4475
+ 429.3025
+ 169.63
+ 440.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page8': class PDFPage
+117 0 obj
+% Page dictionary
+<< /Annots [ 114 0 R
+ 115 0 R
+ 116 0 R ]
+ /Contents 244 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER104': class LinkAnnotation
+118 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 298.115
+ 0 ]
+ /Rect [ 500.1475
+ 503.0525
+ 548.5
+ 514.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER105': class LinkAnnotation
+119 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 284.865
+ 0 ]
+ /Rect [ 515.1475
+ 352.4275
+ 553.075
+ 363.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER106': class LinkAnnotation
+120 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 284.865
+ 0 ]
+ /Rect [ 55
+ 341.1775
+ 63.34
+ 352.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER107': class LinkAnnotation
+121 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 271.615
+ 0 ]
+ /Rect [ 313.045
+ 233.9275
+ 361.3975
+ 245.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER108': class LinkAnnotation
+122 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 258.365
+ 0 ]
+ /Rect [ 448.06
+ 201.9275
+ 496.4125
+ 213.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER109': class LinkAnnotation
+123 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 245.115
+ 0 ]
+ /Rect [ 124.615
+ 190.6775
+ 172.9675
+ 201.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER110': class LinkAnnotation
+124 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 231.865
+ 0 ]
+ /Rect [ 132.535
+ 126.6775
+ 180.8875
+ 137.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page9': class PDFPage
+125 0 obj
+% Page dictionary
+<< /Annots [ 118 0 R
+ 119 0 R
+ 120 0 R
+ 121 0 R
+ 122 0 R
+ 123 0 R
+ 124 0 R ]
+ /Contents 245 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER111': class LinkAnnotation
+126 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 218.615
+ 0 ]
+ /Rect [ 217.9075
+ 612.1775
+ 266.26
+ 623.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER112': class LinkAnnotation
+127 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 205.365
+ 0 ]
+ /Rect [ 73.7575
+ 548.1775
+ 122.11
+ 559.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER113': class LinkAnnotation
+128 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 192.115
+ 0 ]
+ /Rect [ 188.2975
+ 319.49
+ 236.65
+ 330.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER114': class LinkAnnotation
+129 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 178.865
+ 0 ]
+ /Rect [ 499.5925
+ 148.8025
+ 547.945
+ 160.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER115': class LinkAnnotation
+130 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 165.615
+ 0 ]
+ /Rect [ 257.9875
+ 128.0525
+ 306.34
+ 139.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER116': class LinkAnnotation
+131 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 152.365
+ 0 ]
+ /Rect [ 373.0375
+ 128.0525
+ 421.39
+ 139.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER117': class LinkAnnotation
+132 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 298.115
+ 0 ]
+ /Rect [ 493.5025
+ 128.0525
+ 541.855
+ 139.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page10': class PDFPage
+133 0 obj
+% Page dictionary
+<< /Annots [ 126 0 R
+ 127 0 R
+ 128 0 R
+ 129 0 R
+ 130 0 R
+ 131 0 R
+ 132 0 R ]
+ /Contents 246 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page11': class PDFPage
+134 0 obj
+% Page dictionary
+<< /Contents 247 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page12': class PDFPage
+135 0 obj
+% Page dictionary
+<< /Contents 248 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER118': class LinkAnnotation
+136 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 178.865
+ 0 ]
+ /Rect [ 207.1
+ 663.865
+ 255.4525
+ 675.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER119': class LinkAnnotation
+137 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 178.865
+ 0 ]
+ /Rect [ 239.6275
+ 628.115
+ 287.98
+ 639.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER120': class LinkAnnotation
+138 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 139.115
+ 0 ]
+ /Rect [ 98.3425
+ 592.365
+ 146.695
+ 603.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER121': class LinkAnnotation
+139 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 125.865
+ 0 ]
+ /Rect [ 392.7925
+ 329.6775
+ 441.145
+ 340.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER122': class LinkAnnotation
+140 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 112.615
+ 0 ]
+ /Rect [ 332.6125
+ 263.8025
+ 380.965
+ 275.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page13': class PDFPage
+141 0 obj
+% Page dictionary
+<< /Annots [ 136 0 R
+ 137 0 R
+ 138 0 R
+ 139 0 R
+ 140 0 R ]
+ /Contents 249 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER123': class LinkAnnotation
+142 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 273.535
+ 719.4275
+ 321.8875
+ 730.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER124': class LinkAnnotation
+143 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 460.75
+ 478.1775
+ 509.1025
+ 489.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER125': class LinkAnnotation
+144 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 259.42
+ 263.3025
+ 307.7725
+ 274.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER126': class LinkAnnotation
+145 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 381.79
+ 174.6775
+ 430.1425
+ 185.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page14': class PDFPage
+146 0 obj
+% Page dictionary
+<< /Annots [ 142 0 R
+ 143 0 R
+ 144 0 R
+ 145 0 R ]
+ /Contents 250 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER127': class LinkAnnotation
+147 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 69.925
+ 99.365
+ 0 ]
+ /Rect [ 304.7875
+ 617.5525
+ 353.14
+ 628.8025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page15': class PDFPage
+148 0 obj
+% Page dictionary
+<< /Annots [ 147 0 R ]
+ /Contents 251 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER128': class LinkAnnotation
+149 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 729.615
+ 0 ]
+ /Rect [ 425.56
+ 574.4275
+ 473.9125
+ 585.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER129': class LinkAnnotation
+150 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 716.365
+ 0 ]
+ /Rect [ 433.0675
+ 332.0525
+ 481.42
+ 343.3025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER130': class LinkAnnotation
+151 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 716.365
+ 0 ]
+ /Rect [ 397.6375
+ 266.1775
+ 445.99
+ 277.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page16': class PDFPage
+152 0 obj
+% Page dictionary
+<< /Annots [ 149 0 R
+ 150 0 R
+ 151 0 R ]
+ /Contents 252 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER131': class LinkAnnotation
+153 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 689.865
+ 0 ]
+ /Rect [ 180.895
+ 286.6775
+ 229.2475
+ 297.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page17': class PDFPage
+154 0 obj
+% Page dictionary
+<< /Annots [ 153 0 R ]
+ /Contents 253 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER132': class LinkAnnotation
+155 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 164.2225
+ 570.24
+ 212.575
+ 581.49 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER133': class LinkAnnotation
+156 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 465.5875
+ 493.115
+ 513.94
+ 504.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER134': class LinkAnnotation
+157 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 345.55
+ 393.49
+ 393.9025
+ 404.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER135': class LinkAnnotation
+158 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 109 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 57.085
+ 327.615
+ 105.4375
+ 338.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page18': class PDFPage
+159 0 obj
+% Page dictionary
+<< /Annots [ 155 0 R
+ 156 0 R
+ 157 0 R
+ 158 0 R ]
+ /Contents 254 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER136': class LinkAnnotation
+160 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 97 0 R
+ /XYZ
+ 66.25
+ 404.115
+ 0 ]
+ /Rect [ 323.41
+ 539.74
+ 367.5925
+ 550.99 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER137': class PDFDictionary
+161 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 193.8325
+ 174.615
+ 283.9675
+ 185.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page19': class PDFPage
+162 0 obj
+% Page dictionary
+<< /Annots [ 160 0 R
+ 161 0 R ]
+ /Contents 255 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page20': class PDFPage
+163 0 obj
+% Page dictionary
+<< /Contents 256 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 236 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'R164': class PDFCatalog
+164 0 obj
+% Document Root
+<< /Outlines 166 0 R
+ /PageMode /UseNone
+ /Pages 236 0 R
+ /Type /Catalog >>
+endobj
+% 'R165': class PDFInfo
+165 0 obj
+<< /Author ()
+ /CreationDate (D:20100802143410+08'00')
+ /Keywords ()
+ /Producer (pisa HTML to PDF <http://www.htmltopdf.org>)
+ /Subject ()
+ /Title (Android 2.2 Compatibility Definition) >>
+endobj
+% 'R166': class PDFOutlines
+166 0 obj
+<< /Count 11
+ /First 167 0 R
+ /Last 167 0 R
+ /Type /Outlines >>
+endobj
+% 'Outline.0': class OutlineEntryObject
+167 0 obj
+<< /Count -15
+ /Dest [ 47 0 R
+ /Fit ]
+ /First 168 0 R
+ /Last 230 0 R
+ /Parent 166 0 R
+ /Title (Android 2.2 Compatibility Definition) >>
+endobj
+% 'Outline.2.0': class OutlineEntryObject
+168 0 obj
+<< /Dest [ 47 0 R
+ /Fit ]
+ /Next 169 0 R
+ /Parent 167 0 R
+ /Title (Table of Contents) >>
+endobj
+% 'Outline.2.1': class OutlineEntryObject
+169 0 obj
+<< /Dest [ 97 0 R
+ /Fit ]
+ /Next 170 0 R
+ /Parent 167 0 R
+ /Prev 168 0 R
+ /Title (1. Introduction) >>
+endobj
+% 'Outline.2.2': class OutlineEntryObject
+170 0 obj
+<< /Dest [ 97 0 R
+ /Fit ]
+ /Next 171 0 R
+ /Parent 167 0 R
+ /Prev 169 0 R
+ /Title (2. Resources) >>
+endobj
+% 'Outline.2.3': class OutlineEntryObject
+171 0 obj
+<< /Count -8
+ /Dest [ 109 0 R
+ /Fit ]
+ /First 172 0 R
+ /Last 188 0 R
+ /Next 194 0 R
+ /Parent 167 0 R
+ /Prev 170 0 R
+ /Title (3. Software) >>
+endobj
+% 'Outline.3.0': class OutlineEntryObject
+172 0 obj
+<< /Dest [ 109 0 R
+ /Fit ]
+ /Next 173 0 R
+ /Parent 171 0 R
+ /Title (3.1. Managed API Compatibility) >>
+endobj
+% 'Outline.3.1': class OutlineEntryObject
+173 0 obj
+<< /Count -7
+ /Dest [ 109 0 R
+ /Fit ]
+ /First 174 0 R
+ /Last 180 0 R
+ /Next 181 0 R
+ /Parent 171 0 R
+ /Prev 172 0 R
+ /Title (3.2. Soft API Compatibility) >>
+endobj
+% 'Outline.4.0': class OutlineEntryObject
+174 0 obj
+<< /Dest [ 109 0 R
+ /Fit ]
+ /Next 175 0 R
+ /Parent 173 0 R
+ /Title (3.2.1. Permissions) >>
+endobj
+% 'Outline.4.1': class OutlineEntryObject
+175 0 obj
+<< /Dest [ 109 0 R
+ /Fit ]
+ /Next 176 0 R
+ /Parent 173 0 R
+ /Prev 174 0 R
+ /Title (3.2.2. Build Parameters) >>
+endobj
+% 'Outline.4.2': class OutlineEntryObject
+176 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 177 0 R
+ /Parent 173 0 R
+ /Prev 175 0 R
+ /Title (3.2.3. Intent Compatibility) >>
+endobj
+% 'Outline.4.3': class OutlineEntryObject
+177 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 178 0 R
+ /Parent 173 0 R
+ /Prev 176 0 R
+ /Title (3.2.3.1. Core Application Intents) >>
+endobj
+% 'Outline.4.4': class OutlineEntryObject
+178 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 179 0 R
+ /Parent 173 0 R
+ /Prev 177 0 R
+ /Title (3.2.3.2. Intent Overrides) >>
+endobj
+% 'Outline.4.5': class OutlineEntryObject
+179 0 obj
+<< /Dest [ 111 0 R
+ /Fit ]
+ /Next 180 0 R
+ /Parent 173 0 R
+ /Prev 178 0 R
+ /Title (3.2.3.3. Intent Namespaces) >>
+endobj
+% 'Outline.4.6': class OutlineEntryObject
+180 0 obj
+<< /Dest [ 113 0 R
+ /Fit ]
+ /Parent 173 0 R
+ /Prev 179 0 R
+ /Title (3.2.3.4. Broadcast Intents) >>
+endobj
+% 'Outline.3.2': class OutlineEntryObject
+181 0 obj
+<< /Dest [ 113 0 R
+ /Fit ]
+ /Next 182 0 R
+ /Parent 171 0 R
+ /Prev 173 0 R
+ /Title (3.3. Native API Compatibility) >>
+endobj
+% 'Outline.3.3': class OutlineEntryObject
+182 0 obj
+<< /Count -2
+ /Dest [ 113 0 R
+ /Fit ]
+ /First 183 0 R
+ /Last 184 0 R
+ /Next 185 0 R
+ /Parent 171 0 R
+ /Prev 181 0 R
+ /Title (3.4. Web Compatibility) >>
+endobj
+% 'Outline.5.0': class OutlineEntryObject
+183 0 obj
+<< /Dest [ 113 0 R
+ /Fit ]
+ /Next 184 0 R
+ /Parent 182 0 R
+ /Title (3.4.1. WebView Compatibility) >>
+endobj
+% 'Outline.5.1': class OutlineEntryObject
+184 0 obj
+<< /Dest [ 117 0 R
+ /Fit ]
+ /Parent 182 0 R
+ /Prev 183 0 R
+ /Title (3.4.2. Browser Compatibility) >>
+endobj
+% 'Outline.3.4': class OutlineEntryObject
+185 0 obj
+<< /Dest [ 117 0 R
+ /Fit ]
+ /Next 186 0 R
+ /Parent 171 0 R
+ /Prev 182 0 R
+ /Title (3.5. API Behavioral Compatibility) >>
+endobj
+% 'Outline.3.5': class OutlineEntryObject
+186 0 obj
+<< /Dest [ 117 0 R
+ /Fit ]
+ /Next 187 0 R
+ /Parent 171 0 R
+ /Prev 185 0 R
+ /Title (3.6. API Namespaces) >>
+endobj
+% 'Outline.3.6': class OutlineEntryObject
+187 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 188 0 R
+ /Parent 171 0 R
+ /Prev 186 0 R
+ /Title (3.7. Virtual Machine Compatibility) >>
+endobj
+% 'Outline.3.7': class OutlineEntryObject
+188 0 obj
+<< /Count -5
+ /Dest [ 125 0 R
+ /Fit ]
+ /First 189 0 R
+ /Last 193 0 R
+ /Parent 171 0 R
+ /Prev 187 0 R
+ /Title (3.8. User Interface Compatibility) >>
+endobj
+% 'Outline.6.0': class OutlineEntryObject
+189 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 190 0 R
+ /Parent 188 0 R
+ /Title (3.8.1. Widgets) >>
+endobj
+% 'Outline.6.1': class OutlineEntryObject
+190 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 191 0 R
+ /Parent 188 0 R
+ /Prev 189 0 R
+ /Title (3.8.2. Notifications) >>
+endobj
+% 'Outline.6.2': class OutlineEntryObject
+191 0 obj
+<< /Dest [ 125 0 R
+ /Fit ]
+ /Next 192 0 R
+ /Parent 188 0 R
+ /Prev 190 0 R
+ /Title (3.8.3. Search) >>
+endobj
+% 'Outline.6.3': class OutlineEntryObject
+192 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Next 193 0 R
+ /Parent 188 0 R
+ /Prev 191 0 R
+ /Title (3.8.4. Toasts) >>
+endobj
+% 'Outline.6.4': class OutlineEntryObject
+193 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Parent 188 0 R
+ /Prev 192 0 R
+ /Title (3.8.5. Live Wallpapers) >>
+endobj
+% 'Outline.2.4': class OutlineEntryObject
+194 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Next 195 0 R
+ /Parent 167 0 R
+ /Prev 171 0 R
+ /Title (4. Reference Software Compatibility) >>
+endobj
+% 'Outline.2.5': class OutlineEntryObject
+195 0 obj
+<< /Dest [ 133 0 R
+ /Fit ]
+ /Next 196 0 R
+ /Parent 167 0 R
+ /Prev 194 0 R
+ /Title (5. Application Packaging Compatibility) >>
+endobj
+% 'Outline.2.6': class OutlineEntryObject
+196 0 obj
+<< /Count -3
+ /Dest [ 134 0 R
+ /Fit ]
+ /First 197 0 R
+ /Last 199 0 R
+ /Next 200 0 R
+ /Parent 167 0 R
+ /Prev 195 0 R
+ /Title (6. Multimedia Compatibility) >>
+endobj
+% 'Outline.7.0': class OutlineEntryObject
+197 0 obj
+<< /Dest [ 134 0 R
+ /Fit ]
+ /Next 198 0 R
+ /Parent 196 0 R
+ /Title (6.1. Media Codecs) >>
+endobj
+% 'Outline.7.1': class OutlineEntryObject
+198 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 199 0 R
+ /Parent 196 0 R
+ /Prev 197 0 R
+ /Title (6.2. Audio Recording) >>
+endobj
+% 'Outline.7.2': class OutlineEntryObject
+199 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Parent 196 0 R
+ /Prev 198 0 R
+ /Title (6.3. Audio Latency) >>
+endobj
+% 'Outline.2.7': class OutlineEntryObject
+200 0 obj
+<< /Dest [ 141 0 R
+ /Fit ]
+ /Next 201 0 R
+ /Parent 167 0 R
+ /Prev 196 0 R
+ /Title (7. Developer Tool Compatibility) >>
+endobj
+% 'Outline.2.8': class OutlineEntryObject
+201 0 obj
+<< /Count -16
+ /Dest [ 141 0 R
+ /Fit ]
+ /First 202 0 R
+ /Last 220 0 R
+ /Next 221 0 R
+ /Parent 167 0 R
+ /Prev 200 0 R
+ /Title (8. Hardware Compatibility) >>
+endobj
+% 'Outline.8.0': class OutlineEntryObject
+202 0 obj
+<< /Count -3
+ /Dest [ 141 0 R
+ /Fit ]
+ /First 203 0 R
+ /Last 205 0 R
+ /Next 206 0 R
+ /Parent 201 0 R
+ /Title (8.1. Display) >>
+endobj
+% 'Outline.9.0': class OutlineEntryObject
+203 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 204 0 R
+ /Parent 202 0 R
+ /Title (8.1.2. Non-Standard Display Configurations) >>
+endobj
+% 'Outline.9.1': class OutlineEntryObject
+204 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 205 0 R
+ /Parent 202 0 R
+ /Prev 203 0 R
+ /Title (8.1.3. Display Metrics) >>
+endobj
+% 'Outline.9.2': class OutlineEntryObject
+205 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Parent 202 0 R
+ /Prev 204 0 R
+ /Title (8.1.4. Declared Screen Support) >>
+endobj
+% 'Outline.8.1': class OutlineEntryObject
+206 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 207 0 R
+ /Parent 201 0 R
+ /Prev 202 0 R
+ /Title (8.2. Keyboard) >>
+endobj
+% 'Outline.8.2': class OutlineEntryObject
+207 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 208 0 R
+ /Parent 201 0 R
+ /Prev 206 0 R
+ /Title (8.3. Non-touch Navigation) >>
+endobj
+% 'Outline.8.3': class OutlineEntryObject
+208 0 obj
+<< /Dest [ 146 0 R
+ /Fit ]
+ /Next 209 0 R
+ /Parent 201 0 R
+ /Prev 207 0 R
+ /Title (8.4. Screen Orientation) >>
+endobj
+% 'Outline.8.4': class OutlineEntryObject
+209 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 210 0 R
+ /Parent 201 0 R
+ /Prev 208 0 R
+ /Title (8.5. Touchscreen input) >>
+endobj
+% 'Outline.8.5': class OutlineEntryObject
+210 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 211 0 R
+ /Parent 201 0 R
+ /Prev 209 0 R
+ /Title (8.6. USB) >>
+endobj
+% 'Outline.8.6': class OutlineEntryObject
+211 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 212 0 R
+ /Parent 201 0 R
+ /Prev 210 0 R
+ /Title (8.7. Navigation keys) >>
+endobj
+% 'Outline.8.7': class OutlineEntryObject
+212 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 213 0 R
+ /Parent 201 0 R
+ /Prev 211 0 R
+ /Title (8.8. Wireless Data Networking) >>
+endobj
+% 'Outline.8.8': class OutlineEntryObject
+213 0 obj
+<< /Dest [ 148 0 R
+ /Fit ]
+ /Next 214 0 R
+ /Parent 201 0 R
+ /Prev 212 0 R
+ /Title (8.9. Camera) >>
+endobj
+% 'Outline.8.9': class OutlineEntryObject
+214 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 215 0 R
+ /Parent 201 0 R
+ /Prev 213 0 R
+ /Title (8.10. Accelerometer) >>
+endobj
+% 'Outline.8.10': class OutlineEntryObject
+215 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 216 0 R
+ /Parent 201 0 R
+ /Prev 214 0 R
+ /Title (8.11. Compass) >>
+endobj
+% 'Outline.8.11': class OutlineEntryObject
+216 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 217 0 R
+ /Parent 201 0 R
+ /Prev 215 0 R
+ /Title (8.12. GPS) >>
+endobj
+% 'Outline.8.12': class OutlineEntryObject
+217 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 218 0 R
+ /Parent 201 0 R
+ /Prev 216 0 R
+ /Title (8.13. Telephony) >>
+endobj
+% 'Outline.8.13': class OutlineEntryObject
+218 0 obj
+<< /Dest [ 152 0 R
+ /Fit ]
+ /Next 219 0 R
+ /Parent 201 0 R
+ /Prev 217 0 R
+ /Title (8.14. Memory and Storage) >>
+endobj
+% 'Outline.8.14': class OutlineEntryObject
+219 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Next 220 0 R
+ /Parent 201 0 R
+ /Prev 218 0 R
+ /Title (8.15. Application Shared Storage) >>
+endobj
+% 'Outline.8.15': class OutlineEntryObject
+220 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Parent 201 0 R
+ /Prev 219 0 R
+ /Title (8.16. Bluetooth) >>
+endobj
+% 'Outline.2.9': class OutlineEntryObject
+221 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Next 222 0 R
+ /Parent 167 0 R
+ /Prev 201 0 R
+ /Title (9. Performance Compatibility) >>
+endobj
+% 'Outline.2.10': class OutlineEntryObject
+222 0 obj
+<< /Count -4
+ /Dest [ 159 0 R
+ /Fit ]
+ /First 223 0 R
+ /Last 226 0 R
+ /Next 227 0 R
+ /Parent 167 0 R
+ /Prev 221 0 R
+ /Title (10. Security Model Compatibility) >>
+endobj
+% 'Outline.10.0': class OutlineEntryObject
+223 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Next 224 0 R
+ /Parent 222 0 R
+ /Title (10.1. Permissions) >>
+endobj
+% 'Outline.10.1': class OutlineEntryObject
+224 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Next 225 0 R
+ /Parent 222 0 R
+ /Prev 223 0 R
+ /Title (10.2. UID and Process Isolation) >>
+endobj
+% 'Outline.10.2': class OutlineEntryObject
+225 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Next 226 0 R
+ /Parent 222 0 R
+ /Prev 224 0 R
+ /Title (10.3. Filesystem Permissions) >>
+endobj
+% 'Outline.10.3': class OutlineEntryObject
+226 0 obj
+<< /Dest [ 159 0 R
+ /Fit ]
+ /Parent 222 0 R
+ /Prev 225 0 R
+ /Title (10.4. Alternate Execution Environments) >>
+endobj
+% 'Outline.2.11': class OutlineEntryObject
+227 0 obj
+<< /Dest [ 162 0 R
+ /Fit ]
+ /Next 228 0 R
+ /Parent 167 0 R
+ /Prev 222 0 R
+ /Title (11. Compatibility Test Suite) >>
+endobj
+% 'Outline.2.12': class OutlineEntryObject
+228 0 obj
+<< /Dest [ 162 0 R
+ /Fit ]
+ /Next 229 0 R
+ /Parent 167 0 R
+ /Prev 227 0 R
+ /Title (12. Updatable Software) >>
+endobj
+% 'Outline.2.13': class OutlineEntryObject
+229 0 obj
+<< /Dest [ 162 0 R
+ /Fit ]
+ /Next 230 0 R
+ /Parent 167 0 R
+ /Prev 228 0 R
+ /Title (13. Contact Us) >>
+endobj
+% 'Outline.2.14': class OutlineEntryObject
+230 0 obj
+<< /Count -5
+ /Dest [ 163 0 R
+ /Fit ]
+ /First 231 0 R
+ /Last 235 0 R
+ /Parent 167 0 R
+ /Prev 229 0 R
+ /Title (Appendix A - Bluetooth Test Procedure) >>
+endobj
+% 'Outline.11.0': class OutlineEntryObject
+231 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 232 0 R
+ /Parent 230 0 R
+ /Title (Setup and Installation) >>
+endobj
+% 'Outline.11.1': class OutlineEntryObject
+232 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 233 0 R
+ /Parent 230 0 R
+ /Prev 231 0 R
+ /Title (Test Bluetooth Control by Apps) >>
+endobj
+% 'Outline.11.2': class OutlineEntryObject
+233 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 234 0 R
+ /Parent 230 0 R
+ /Prev 232 0 R
+ /Title (Test Pairing and Communication) >>
+endobj
+% 'Outline.11.3': class OutlineEntryObject
+234 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Next 235 0 R
+ /Parent 230 0 R
+ /Prev 233 0 R
+ /Title (Test Pairing and Communication in the Reverse Direction) >>
+endobj
+% 'Outline.11.4': class OutlineEntryObject
+235 0 obj
+<< /Dest [ 163 0 R
+ /Fit ]
+ /Parent 230 0 R
+ /Prev 234 0 R
+ /Title (Test Re-Launches) >>
+endobj
+% 'R236': class PDFPages
+236 0 obj
+% page tree
+<< /Count 20
+ /Kids [ 47 0 R
+ 69 0 R
+ 97 0 R
+ 109 0 R
+ 110 0 R
+ 111 0 R
+ 113 0 R
+ 117 0 R
+ 125 0 R
+ 133 0 R
+ 134 0 R
+ 135 0 R
+ 141 0 R
+ 146 0 R
+ 148 0 R
+ 152 0 R
+ 154 0 R
+ 159 0 R
+ 162 0 R
+ 163 0 R ]
+ /Type /Pages >>
+endobj
+% 'R237': class PDFStream
+237 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1796 >>
+stream
+Gatm<9lo&I&A<G1rrL0IdieGHa/r+lUmX9#'<=\8]tbm=USS5"U?p":c[qBl;R&e!c<0,cOB;Lpn*Sj5-mJ.Ng],5*TpIS-i\a/hU"LD_JH_KJTKd%d-XYUMh%#bQ0nrU52M:`<4f>o93$k(MM=+,7?rjjG.)f=5d;4Xf`UFc-pFE+CqB\`1k8*8!r<:IF6aL.SeN^LWYIfRNLRUm+*7K:_5O`/si]$8>na."-7'b,+`G=e*s4D+g32M;i,Z?I23h,<,8?[^oSB^4c_,GGngH@[]+ii$W#qkc_e'?#4d^-7JDskAc0;%tD4Q,d]^G<jOKYJ3/P!#s1b&PT&joE57p_fe2d6F[)B2&]k@H`t^Y#Jo69kBc3kZlG.D&QpM&V(@7bK(qi]iatL]5aJ"S=\7"P[GXjQtD1qR#oMiM[E`13XL2,!A&S/=5TNNgbe5%-7NDWP2FV*CDW7*DsIJ"Z`6@ZJ2M@nXkg*3EU1./]N`Y,;tOSl]BZ,GiGCZ"^KsaHA0s%W-Eq'OLa<!4>Q?>6C$.Kq`(+GF1%2X)GCQKm_,39!N9`sbbrQ\?#mhkk+JO9$!>UpZHjaHd*+WdP<=@pKVDO!FSLL?7bujGbK]tXH,fBE`HXJBPR#d/)#<To?P/c0q;sZ;L!;?@fL=%B^[Mr<3p"26ad?U7]GKT.emJm8Y$nRq@@ggD4M$T%lmq3uD?Lf.s/ItFt>p(9$mo6D)\jU1tDhgA1*^\E]0uRl`U]Q4;,nV:8"/]"[FQjW1FYTOMAK:K4#3$g&>c/!0J?d/J0#H<0isM/YC:?%c2=Q$GaNW]6Eau*^>q2b<]$YEDKXWB6>4cpp_"B,6&qU8&C`!!P$8W+E^D`"nR.`6>)j,dsSdZ9/;Ol03`03Ik$Ah4J.,Nf@MNb7QoPafiYH64:Cpg9:TtJZf&IQ=:mEtiNX.;'.Pk]O!HO@Cjd]?Mb;DPqN!3S>_b!N5"a#?!&)Bs,=_jUZ2AY>\YZoedDP^r"#arVk'&BskKg9!P>6Qr%.o_"ESOCohB55XjacmeH$!TY,sgR.nma&;\CJ=q9JqX1jiZBh#)cp0cXTUa%+PRh>bK0#/P:tPJ=f8'Za"kKu3_uTI==]A`&1E.4XMf<Bo\4qdGqF99ZlVr!8TLic9.ShK_T8dVEYfJn+gmD7eZWMt0hjuf6e(bpDHSU;Jj,WF<+^:Tnm8%0;7uR6\'.MVtT'qC(5jAg5W!qAt)Uh&b+9OC%Kqd>FKb4cF,K7U'`]]bs6VP&;;tVs<Wq"q(B"fk/PN2Vp5q?$l9FV,AT38+VP;>Ok>km%C79.l1XWHidVWl)F)mS@)O`H#::skt$<"BmPN<b5-$N34FVE.3e(PP'UcF)+Y,k:;e(G5ktZ?f6tV(2IG$WA^qB)pb6\#C:Pe>6#<QP%*pmJr!l,X:E$i1QGK!aSi#0nDdX7#r(?C=4/&[h1370q)'u:[58\Be3)SYc\-,`lI],p^76gD%Qja:%L?X5KKRi&B85m_3l:hU<l(4Wp.(.eWg:u!ZA=7<,O+\Ik"NSUtp,h',c3p\.;9mDm@;a3-efDo*e07DUtj\76(H\O6m5L'(*lKLqD]?rdH,m5"j=0ir=Z^%Ni^!lIO:b)HE+hQ<dJg*U2?12K$)AqcW\8%a]sMR;lC!(;f[SW.:?`\gj6$27hMC<n9,?J7^q?*jF7pV+:/l#=ep^S+Tl`:HNQV3BMl/k!.mZcurcGl#5/h3%tKn);8A[pP8@#2N?N,2fLO^2%0*;SaaOoJG^2P&'jCM#r\$^O+[,VS[GFuRkV.@e!'7cBaW\~>endstream
+endobj
+% 'R238': class PDFStream
+238 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 946 >>
+stream
+Gat=)mn_[l&H.X=s5?.ZPNM\(3)2ZSp`ZGa?jYQMOID>p`$KDSrqF%71hdgaVJ9(!Q[:pRq7UDD:-Z,cGm//O_N.UuoH:gL$s3Mo0/uNN#ESSpf5qUTk:nCkZP?"*Np@OGgdb/UoAkF&`P.FE;(*Qh!0PZA>/.*dRHR7`qeKg5`VU#,?V%rblIY`T>eaOYh+WW2\!Gcd<Zcg`9b(q-knPEYMb$/<+_Me6&1JdUM<'g`>%C>(pP6Ni0Fh5NlO*cgcY4FfA-<bVk4'0adeIL;I:NI0IG9rfD&.*sMuZ5kp='*fc2sWpqToLI@,GT6Y`Obd14fpZhe2"+),X9R)M*33he74q18_-:2Kkh#mhMfC%k4Q?NQnHk[2Y=&S?4U'cp1[Rj36C4"10h>=NKDI3O3B:e,a?-Ch?9DQe>:lb=nUFGYlT7"Vice;`(LRD%"CPal$'bBAGZaoumR\1\dA<Wl\M/OY\u@F"5c)8f?/=JWNLfC7_h.rK%c0fi@$rl8(tF1\5s!0:`(DK*t]DAdMU'KuE1%Rjf_\T[)`lZH-+FPMBf1qV2EGKVNR]N7R-?)t8DQDL3X+dG;&d\W(&k(EHkZFOUJO%:(+4)2KC#U+6r4N)<^hl`O3.Vjf0:F1%`t.;k'L0['K/1Z1:q-7W@ZPQr"NWld'_pftohp6t:dRu>B2pTuqfYTV`IjZFH`\!P9HLeRZW9J/RG\f<%;$JP*QMRFgNZm-qh!l$`[[L0Z^FP[neH)jRgX:Zierj3fK>II"$T.!:B5:jp[lHCY9Gp*Ap'q`uO7AK0@e`ND;7]@'>rn`gnTFUOSH-TJ:MG<Nc%_<V8M)sB\n9Uku@0;(RRrtV<3&>2q26?IDG2=-.(55UI:UHnDHqLm(D5eZ*GNP=[GULAs.b,lh%G^;\$b<pMVo9#`_Y:mN<u\JfSM&bLoaY,4EpsTNLkcQ~>endstream
+endobj
+% 'R239': class PDFStream
+239 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3247 >>
+stream
+GauHN>BA<(&q6a9s.ILu/=]>nqi*OBQa9Z-/kb=X&'HCo@r#\`Yq9J-)013)BuqEW4dj6[93_U/Htg"&YP!%IC^Z[#a3t"-)+&7RaEV>@b=8fAZ<Zajfa%08m.n!VqT!>gpKV7`3:PjohK]K7=dsIl0HJ@1d/*PoY\LQJ"ZZ-;1s:tl@CQa>eVF8"e<$R,;_HH*k9ZSqK4b/3U]7<C^2FM\giXsJI&mR"`#fi@0jR#TkE'7bgNS8'V[30.d!0+HbJD>9cS5g&pUMi#;T4ghr"1mb55J]@,NhWQS#r&C$'2-Gjq?&]I[<H#J`M]_P('T:8_#,0Jk2,+6D?J/)3p$>LmJE"d=R]5j)^Ma<31>I*p2abQtHSbC_#X[9Wlb.4=N9`&:fPVA)ING@*gp8n,*%OkKe/_QiI@.nZhC/Z4ni22Rb&3FM5k;K]/LW#Z=V.MYI6Y.!R?slea,RqR?P\;9*-7d^20ig`]_28sAYip.7L\^ea6N1NI\j8=lI^?DoP%klh.Z$=H,]p&<Rr4!Z*,5g!U>mu)iO=ABMuf&q6qD9Ig`htgeF9f7LJ<:HoHWOP>sH`<UkIh1JZp5\4u.+DT3"hL:lm"Y!U,3U5E[k+D4AOWVOQ^/F!Wp$1$!ZiNm4Mb#;_p=M,m!hDHMnf<eH,9%tgp7&Ef;,3si!ZLoOPjiLmjkG$LRVJS]+L'0hfhImhsmO'a6FuFaC'U<r1_:6]U0bK_PbqGB!pfRJK+Y=O"C3%ZkjDGC@m1l&9>u[T^A@?a8&8#VObPU(LDKsJj=[[gtE9;NQk"m55s_k#3#sSGu%e*OpVqmgR*HE^rTD#n'E_&,r5_U-/9*1<MIAe^M@=dW:RYQ\5Mf!h(f$V/:`jFVW.cuF2L&4NQ'L(Z#b)=+4,!hYk2=(!&rComXUCGDU:DA[JVbb[N:K;X!"-CRMc?-#>J6UneQ=7X[s(PF_MNIIE#k5*k8A?V!.-&\$PD(0+k`@/1#%>O?*LibNQsghNdW;5ck_Sd41,Z@OVJL1"]MU#jc=ugC=3,77t,ViZA?KdBsa;oVppOcr`Jt&aXi^!G8SS&*a9'\dW';'$VqtnIXchbKZEs8Z2k:10_M=-.>RTl3[3I!IF47l^NOt0I"e)(]+f7p['lclmTg;W'.O-B87K#(!7I3O'bqlQlF[]2,MsoD?E-h)5bkj2J:3j=26!7TS0!K(_@4g8N*5$Ki7:b?69G?<F9\n%7O97CV'?KV=#qCoEQ%-C!r$KA+WO.#_SG-#c1lU"Ji@COD6Ol%U#[#;58?H:b)*e<CZ8c">ek.fbj@(GM99i<;qTg4^Y(1J3XN<O<p8modpc5$HgNIq')DG?S8>[Su!^E5dg=d?:$_(FA_Vq*Yb_dI7Q'gZ;Lk7i)t80TpXnSF]ZBVWFR_7^,qU<93S,:#"Nh4,q2M7LR`>0;b]k]&njqfeAZU:#nrf]67d!*Y>Ra,Z0Y&tRR&em=61oV=Nsh\.[bH,irEN)((1mZ.Epe")gi[!IhoYi\.,r:V+n/7/VC^%mKl-iXn?U2!4S?hVqb(=#oLD:n4V*i!UYX2A\"8QV:%;+pH^Mc,ln<fRAd%.A5r^>[Tf(R%eBpCRO^'>qP-SabTu*K^!iJt#qUZ'h6DRq6L!l5e&apZgTJNCr]*i/+*[0iopUU/'baka[iAJ%[I"*6f>^k#3Sa!*&$#,@)n'Ig5&UfkoKh$qiYC10[[!)r/&PJmf9fFG^sIiRjW[`TPmK!kaRMNNrZioH_^KknKtAHh(;Lu]$fq9Z(.dPm,T6F\Wj>o!f+2:qa"Jd!o"uA(HE(F.BXrWNQ-@\Hcj)q->A$=\)+G]KFl`:?4(&BkJUM/*pS@3Z0HZ@X(ZB)$FbcZu6-GdiIQ1qqh=,75IX9m#mW9di;h@af%jAU=)^p%U[fqmkOSB%.\Mu:G?%4?kp-uuCJ0V6.^'@+&q7pnMq\(P;-A3_=7IXF;S$U+)P-Y=V't@qZ+39/r9L=Cs9SBAJVRHaLT]&QqCgc<*^St>(S<!_($uPN"g`[,&V!Z!SqSg=&ePE;U2qOX4!C0Y`3dJG?qaet<#P83s2Et<[$t`MDBf*7.'d;%u-inuG1s!^'(Oap$/qpV7rgM,NR)E@qr%BI.:n0l$F_^-l2N>`=@JJT>1K>'D"po6CCmr'6h1PR[4'-.lg[*r*n$+?j%K511WU"Y'cr_],Y=MLr,HaYS>[FOXH"1C3m]lm,meAi`%aA^V,]bW[%jU4EeK1,lQ4/<<$V>9i%Jl!JZ@ZE],DfJQVb#dr[_T(-4!6*Cm=05d8M8NtBqiii;#[iHk#KHg@6f6j.cIgj4&8kqg-K)V<A?KlDF_&&\gY:sA4bm6U9Ue%!d.tY*@-T$IFG+DL+S(h2YequJh?kRb@-occ9tiR%C`<%8`Y&k,Q_AKn^Z]68q,rD]*EEd/!:]"<g4H32?eB53GOME^^)@R<804H]donI_!E]e-nV'#NMI#*gE!DOLf&bWQ^f^-W[ZW^e4u=c8D7(S0m3UAFta@E,MHE:"pfRMjk>f6U[dSl1aUc#hc9fl+XLU&XuGel7Hj5*T8k'^g$Ylm:I:+(-RBJ:<@k26*lf2;ku>c:\5a#DloG#U"M)m)!bo9DUl8B:lZ4Itb#?J_.&;gU@Unn\ARq6.AX_S<fsS&&p:$U+&3C,54-(_!`ecZ3p$_,]FLjE<Z/[jK_I0\)1>Fqr2Kmn?$'C9cs83ja@(-huJI]76l4]p[a_4S.5tXtX'Fn$FGI;>USNoa(:;b(j-Og\'Gs*o*+^%T<I6k.TqCBO^d28A9$RJ=&$D+nFpc/h*hjc5R%/8(KAE'inDFT',n-"[-F8I_!Eh;uKZ-h/>M@brpU!k6?]L5>SM6ARnan4>koaE^>f^o+)0YZ=MU;UL/n&5)<=G3g4(Ch&Na7&e_?RAJd:5U!t:`gWAPn]Rd3;fmGY@h!;GsX@XkpaL2\5QrOHaoF:D&d`.S5^g9s3)i%YK^hb:!"itA(DK3&$D;r./a9@ChjqQL)]qbFcH@5'r_,UdJL60g#2Z8^!iUekg*X%DpBP0RC7GD(XT*TP[j%l0;*0+k684+"kYlorVs^.oiq%H1jVZKlJVmB^r1l/UW6EOcmq^b/u-LH:\FV6PM6_sM2?HqdGA)Ns6V68YB9L9H]lu\;=IJeR?)Z,*7E#Q>Z,n'G1a76(U]BDU)r6;?:&G5r%d8+[iOF@LR9d6VL<Vs[b0k9a09UR>FmM#Z78ZHhI(O6JRP<dp^jIPo4S(.k`(;@~>endstream
+endobj
+% 'R240': class PDFStream
+240 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2935 >>
+stream
+Gau`U=``=W&q3VVrW?nAf!?Yg]ID*013U+343hAGmC[9/JKc6F1F/XoUceYNgC<WPAKCCTDsU(1*8QVBYJ4s?/ofgieUOJ#+n(b.p;&&X8![rM"uIIG?c^dgm@/%jf56h/!V&8jLTkDFmZOR(NmZML>q[IIDr6(E[o4!iGncEQ6!Tbn1rr1H0b%!VUOV>V\HmX0b<O)=mooU,qY+4kiO=5F@P9]Nc!_8:bmUnS;h&oK_MbA$%*c)<BLI@Ga4iO!ELhnT3$-HiS:b)NnH1c;]Gnr6c+kUbMU!cF7^0rWbNt1OOtr5QB=+gd:+s03k/mQZX!CKk:IL[djQ"rg<Gd5Sbqc_;\_&Z/gWc]GAs09aA7`nqc0,R)cA!P-VCM-p/5sa5"!QBV%ijVp_@qt;O6=I!n2N7\^KYq@M9PB#alq&B_.<,ld'VeE7blJ1&hW6Zri<tK4sDU#Fi%S@KH:Tcf$I&Yk(]-n8<O<'1L;CC,AN^Dm):/YjBq:V=Zmulo2ggoid>R:OSXlDcGTaCK)"G;o?K=Zgp"/O]XfKK?1OE*Jh+f/WCZ4Ha+`ifjr'Xg@LH-n;iU;7__].D]<>4^I-5=AU4=l5@A&"?IZGIpT@^.WU=t]QT0GLuF&oEI)<BbKaXs!^\gS3e13%S!kJh/%cZ8L-O+[3oV2sCD%F0)oh@m.@eV5LWQr]rI.8pB5K4I[H*Qq!n,tk9Yek*a%mXK"$$J\/*<:QnWDD(rHdA_0,o:2m!=k@4g6,Fm-C]Wad'i1$`<'kNbj]]_L_$0<GL6;m4r(XT5^;r]G(U-Q9U#]]Td,HlZ@-$,JiWks_,!Uup$VOM_a'?;gCL2$5'l6?._tbTWTVpqf\/AAiX^ii>",LnJ(dJ:?-ggD3WsIobJJ-m_'&8c%eODeZ_q^8LnBO1r=LosS\MI844BH&D`=CI3k1$JF'*TUp?K5"j&j)s8@7ah^Rfu>LkXBI\2Na8]+n,AQbTZUH7ls*dPWTlZV`=pbjZ>c8G^r!p^_#I:7,WYdR.;/J*cZUcL`O:XVrU=K/$)q7m/ofaUM&`8^h=iKJ'>$&Bn7<ddg@hbL(.%9.&Q$%,UH8XL;]l7rG\`ed>gPn,\/2VSV9[0!@0\lq*BQnIaF"/Wm_DKPfChcZ3&YjFg!8qi9i5UGAK-2[bDd0VEp&C.9U,#5]tIA/bi-R2@3PK.Pc<lp*&3N.(PTi92cd"'/\a06"\$L.?bka1(;)m!-$5,$(0:R*MqAFaj*;=/(`/,!,=I7NXH./?EtT,&RK9petnTTfDiQfC?7]"3]"T*9r<<=JV%j?1>1-Kn.FT%r"7k1_B>;n++i7@nY3jC6u?TVfF3o0;KCS<@E:j3m1$qrXM&8_DHH&;$$Csc.s)=Rbd!1nkf4u?MuKmrQV"pOInj(\g"Ft!$2Y+!*K<Qim^NrWL(ZK\UUud2lRgep%8V$n+2HcNW`eQ:aC^3>OBDUr7D[/OdK-M'i7A?m!>s4_CJs^g1,g-eR(F)@39Gg0!0MD,)BE!ZHedM^m:2]AG>eW*j##OoojIHg+W"+5C!]m&/-g#9:%0-))QcSa>AHFPN<?SWr+E3AqU0Ne',#Cc-E-qbT3[!a4;"^54BkX+9G;Kia.Ifd&lJ-jqdtnOEsT'pOqhlMS)UomdBu@i5j-5Y@b*Cu#CJ`jNKL+</s`?$MCf*AJ#-sc26DbiZBVPT*.cYu06,T5k!TS5hX1:dT\>OcT@>u%Yb/aFILr,/pA:(mlli^Z["h?tC'2AlqPL6[^u(?IB6#:&KcZ>Mis>hmHr0?b9goAnmE>7",m_aG=Q?ZT6bpn"^9X6.XsP08[f&YDoE^<j4AR4R"pdNRZUelI9"Kb04f,*]2.Y?HVq=XC"-Q'LiBXS[nVJU/mR$8HUM2qRnnF#&VYPPb177'<dEZGu//U)3_,A%%Ho--CjJ)*id:55WZOb(46Yp1C5f'oN$:\7_62!LZ\j8&p6b6BQ"R_JYdo>q[Tl(iSA%J2F1t=A7"A[M%XcSePCP+Yg`u`A!(/lLr97X\"US]m@53m,SE4<AhVi"IKTLb2@U1-.o3k2W/loHET$M?@B%o)<hA'i.@Q)XG"Z#!c[80KaSO2m_+qfG#nigu#d8?)>@cSP,PJ]<IR9ZEP-V"mF*H#p2@L2h-,([W`6(II_,%IJf9-*LXDQ5VXc1+qm%"n`k&Ym6^OgoK6cqr"sS\i4W&W-2IQTMp)$dQCCl'_7uHj:1QRAS,laKd)e0`O$Wc,DjZ_VR$Pa=7hGiH9lW&=',qZ5_]TRR-Qd\]-OSbjJ5\(=kQ(F29ut:ZHD]h"jMa$WbfI$r#WgrY39Y"@]G<2#\qjh]mY+OO)L%,DD,f%0kYl[\:N25[#WYGR!f5o=n162chd(5h<X*Z=qj4!1.P,"k>EfMQWdZQNB<4<L9G&%FBb38``]-<#;9c<M(b7MA>6hGIC]1KlR2PjlBePq2cl(2TC3kH`]e/*q0T7dd:bgtmZoqYTXTVd_9kn.E7\bQg&]gj=2qY=htd5X\`CV]XXbU,B>ShrbGe2FIHOS8,h"bhZES&`eslc9lbnB%Ma=5G<X\%C#W=]s5=sjg_/r0p==\j[V+sOrpuDAU-0t)D'TAn!FmtIh9IRS,18'LB&9LcD;@&cO#S5aUE1'Gj^%ZuZS^3stI'DI"TIZCs/m/:UPLfoZ4MOta(2B_$&t,B.Jk,fsIf'9f']G[Om/MtmL]5!)b_$sK:3Fj9:=+C>fiDiX(#=IR&6ClI=.^&"q=^J_AnGtBMheMpFt<6ef?UfC^!I^r&Jm>]H[GHDFt7EhrLO+h4>)!!8Zg6-c?aFF-O^e-m1N'%4#>[@S^a5hT+>ZVHK)G(>h@70pH6gT0AZBjO]*<f4lW:2k$r$e1>aIq@*hXMCSEn'46IU2Z?Q9m>&]buE:lJS=gRS9USg*ro%])UD:Y*`hiP<crWagtZ<.~>endstream
+endobj
+% 'R241': class PDFStream
+241 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3185 >>
+stream
+Gb!SnlVH9V(B7^?s2,,u%r_]4+)sXB7SDrW<M1;ZPu^5_1A3!`efL_1Rl'lCh_Sbh4FZ$:E8(bs3-0Q33TloX(_*J6XmuF.+/*m/1qM8"VPDZ[Bk(_5<Zf_:p%HX3r_H2Gjr!?o1,XW\0Wq**/K7WcWhJZ(g:r%<;Dk.]WgljY[.9?V.6n+59]K),R7``oLDt>OStOWkB_?;Hr=AnrC\I6ffpHhJ3M5Rt=.P3+C.HlcUoE,e?#h6$24+mfFf&jKoXsN!-`UJ?R/PgFL_BuqUBFPA(V?96r&J-@0CE_C`U3Qar+:Di]):4?Z"0/<R`mI,C+@5FJCQm`=I_iJ1&<kYM4Q7O`lR!@'GL+`5g^>l#=#aW7]sMtY`DA/6PuQcL00R22B5&-fQPlLSOMZ8Oi7b5CJM:t0EaT.E/),946Be78W46Ecj9NHa<bL=q\D1"Z/o)K*YtL$60MO8JlZ*BVY8hn^0dSg]+oY1.)]aQ`=;qdEnp=+1KB7sVoZ?;>`eVh\K2EDU&\W]+Q*X,JhBoBfX\HPZ%9i*d'RsNGQ86SG)6=n#c%@L[C7G08aJZ.83f<Iim>\XG!McUn0!T(fg+=40F374R(Yp#2\oqA0YnpR'[g*Z\4#I/G_%F@+TXRt20M>.H&;Z$Lc7qX;`+>MLrA1e]Sh:C&2u(lNPqF/ChD,"^P`SX7Nn7gLZ>/)LD-LkIe*\#a-nc/opU8PGIb@)<e]8ChXTFpAubg"l<S=B%NQJRc"/R1.D3&TB?r>gk?1)[9p)-N\1WK2>sPC48=d^r8Al'=:`%P9Xng!;%$?52EL7W9=>N(_KsY<tUY!WYnT4uMo[hCZjlPm6/0C>`X781_I\J?]p6#_X/3hD!]OBNF^U)#?'IJ'7&bj&E*!PDfkNA&p`0LY-&_RLJm/ZOj^klpZGmi^VA2TVU)H725gthl4_-E!CokZ,eH1(tgB](na9;&LCZo@oS-'5;<5?J72ljJSbB:bq6Y3(3dhTlGWJh_VgIFnM/j23KZm;CpFB0DaBC'Snl0Y'%0ETHt`67.""<59)VCs;%unq=5X56kna0b<^"V=!"2-"ruB$]2b7e<oNY3\b6MS"SAkgCNo;Vrco]eS_Esl=3PXE(S`(QE_+2Cp])F<(1A*qG5hodmh2%2^[tE(jh$cgIm_u8@Q$c#i5N(p\EiLZ?Nck5bR-Y9)B6]j%6Nd4>5>7,2f,uo:XW?nF3aYNinAcT]:Mb*:q_OiFE(PT9a\&TAQi8%nZ(XT)$+jiT(%]ZX_g3rc*C4T@+OTJ=89$_R97+;[Qf9I^jkeiPnENiAl5o$&u]&XJ"m][;6qGr'O@p,CUJKmHjS$Y3;YVo)3Yk1(85I_%%q)IZ-4\#h/#($U2p@X\c,rE,b"HG;(7>RCU90@Y^R_5f1gP=U26!bDu?(BX(#-P[BeW/'Zu^gG#q=bQ<j,a5@9A*qQ?se1$"l7-/IfI%GoFcK->W-eZq])f9$&9WSfr:(`J&(oNlS-4ZuY")(0N')oe[PsDd#LUm[uBX!(gY!cU)5Q#\KhpE:`bEpf;_I9ihb`p4jeMcJU5U0uLfdW7N_'2.ERk.OlAGqs4N'9+-TDcn]Zl!s%d)Si@:Ut-Mq-Kk<2\`O8==4V[2'50O_+GmlE9iZ\m+ZBM5GlJ&G-%o]IRVcHk3j"I>@,7LA4n:\d!-#.\bs;Pq%ujRA@%:ZIR,8tSX:X^9A*<Im*[K,M=qcQ5_F3tNpjqK-MjcK$0dmUF6!2([;g832'6unX3J//?ghsLDAXslZlP0*/ni428?aHmhtXj]$()JrT#IEBQnT\;0=f3,B>G@,ZPn;/&M30#&*^X5E2b>X<QP$>]WGu76K7V"X_&&WR*Ur(ksfetiYqh%=UPN%"Zo2tF+e0]K0"^n(?a(]7p.r,,V@]G;Q`HE?lN$ZKeD,aJ-!S[h\&&^GgFU8b?!i0d]2lEB<+(=rEUs9oF+@C=li'KlC1m;n9sV]ign'F\2_Q^Q'Y:;[@o`A+'\!tGo_\<N$9q3d[M3?ginX9@`#9JY]IqtDb'@NUj,AoQQ&Mb_u9mqfNTnb&^h>UOEZq,L=l$P.jK:0:/0&AIGnKaDMDH_]tB>-:P4:8Lah)VVG3!+UdZuP/:I4r/>$PWS%n0/#/*)s?iL\R/hi$N6O.Jj?E/g.XtiS((AF\79\>jm?(8"Yig%dpl,JP:F9Fu_6ehkq$%r&N]7;kG?*_G,[NWZMQ#cSi41,/*o[A`2CtVF&`-Omrf5nl:CnN"HTQ(BC'F*r=T-^0php7XA&h:N?e:'*N$J+P+IK.A3gL[TcUW$4k\btL*0bCEG$@KQcYVBgeHpQ*8fK4eHp94&0?:Vc:3<'EgS?T1G.fWh(@):rU,s5?pr(P=So$Z;\pMAVaa.1"q(MOddO>/(95-APY!a`oQ!pHLf!>NP"aJ]?"^VspX:'.d^=[It+N@rh.e6rerOT8AfFk.7oA8?LEY>\m0#aIfc`2FEi!SQ@IpbH$]-O3Tsj=r-XZB(!r<$U(1%;3c`<=*g!'U[$!ee+HJL&E5q'%Ibm2A?7L^Hq@#Zt,4#W(IUU.\Xf$7Vf#dm'MMP8:[^n3bo'rPo4@u:8bu.&LrWPM,>d\n84QBLWX/I+p"\V7#X_dnZgK1C*YmC@4W%a.\Y.V!`OBa3hk*&Y^_<uU0;$UMW0.XZ9Xa**'I/7q=;VfJ4Y$SDN.hhArc#\.UPbg"te.hLY$A]H?l(iB^i]-j25h&nPc`pN"6`O\XtkkT'EZs@aLd%A,(!D?.+n0.ab?hVEnaZ7lae+:K8;P:>S83.6u=G&IKMp0:A7kf4cc1h5H=,1.$PeU+Jl9,$F)7UYp##A_&1M)sE6F^:<Y98l@0Q,sL:)!K_c/f3F2'Rq;j>Zk?_GZ\0r$]$]h%%D=kW#\`kD&]';nid,U7,E4aUh".%P1hnR3V-,$5)Ke.gN>\r?jVBM=AbY[NB5[4H8n5cFA3l?t(hBM0Z,/RgR[#sZNSjCI(hBM0Ysf*NV@pR'0C%YAGTrMiIAp&q?ul)--Y,e=2D4$D2_m+5Y0eMAgSB[7Z>gahd?FaVdAuf;8SY/911QMd%<T=C(n$-_!q4c2/Q][W9(_2T?>Cu"/R%r_@aoEu[-$"]F;qo1&`:W=RD$`*#'t`d<#Cj<OsEBW2,ZdM)RM2_>"'77,ac`ChrILaa=`N/2T_lXEXod2o+1QFE6A~>endstream
+endobj
+% 'R242': class PDFStream
+242 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2279 >>
+stream
+Gb!;e=`<%S&:Q:Zs"NrcAd_*Ja_0<T2a+V%VJ-u&('X7q9=2r5,#sf3li$K<6QNlS3SP<(P,>\+A%oK5r5OLJr:/V#0EHDYKKn>gi!1qUKAZCV0ROD7LJOOiF2*/Y][MTXn9Q+FZhE10;nm_Bp!-`id"2#A-b-0`D:J1Rh$si,n9kgSj8-,mcg/rDBC88ci2$63%)9[KRG7\(qu'QEpp;JD051ANBnC29>$g-p4Er5*QPM2QOtnOW+r5?ALRdZsG5K!T=2s&<f-G:*H*',b*6:Z$&OC$=.0(3h$<T8&I)[=1b4'Xq)QG?JGm"2(9JjUb&k:[%3L@P01_ud3Aipo*K`T(Y2^IB0e7+)HC]5n!RO;tTc!t@*2;H8JH)WdQRcR_A;J.A#at-fsI6GNN@&g$N3+oV6<G*N:+;,BF(+cqD\U[.(XO./Z!@:;s_kl0][+4;<Y4E*#X_&d:^a,-o)'FSMRLk^<CT_C.\n!/LTbn.?`une+2's[sQEc6[D'i+f+er;?pnc]s5cD%Z2'KCWRgIk\N;kje^03MMd#;&`S%<7I_W?1V]j5[r/3TYJUACSgrVE8VPM/7qI(tEJ&((P1QVWUkS0__CY@NHFO+h],PZ]b.l_uTVM6Apa'24--@PfW)B1&!u/EXMM+oWi67\:CkA;DQR.<XBu,VpWt1hI+67UBI:.-\Pu^?/BF:2/X,n--]4-_\#Dj-k*>?nNu;5s?Xc#mTZ'-b1Y(Xn^1epX^kn:Gp17inuHs%IOckO$sl%/m8]W[^&7<W\+t3TM7Lon:h#/4!SlW)Ao6GMQh;Z&\&%/Q.B$u=LStk&:B"JDFGPK8@:&]-5i#4dKgkaVG(LJ=L/bIIk&<>'Z;C[3P\%rmS>r5.2^&SNn'X4f:'KK4(T;Z1Z_jX"_HJVKs<aC)umQ7U/$J3\c^H",V&l?#uH=bmu*AK^XmOIO\iYiQ0Y?F\mBAt$Q$&TDsO08#=f*nV,hZTFa]eSk3tkKoqKO]os+@a]*l$e$oQ85n59LA4U[9->VGU5d&].RG5qJ"@2?7?IA":!Z,Z(pKSd3&cu*fuJbk\O=AdYa41<o,`u:dm@l7`c2.nt?f#QOVZRgF0@,J:aL=67Meb6[=b2^Hup%1bUH1;eqP@'X[hOUTmVDmuT\p2@qI%08N<m&N#mdc!3I[(131]`p3.sL_Yi>kWBXNRq,<SD=ALqD$>f*)9(o(l\5]D9.ScHjds1i6K<A(ZHLq4!Sa?NXtH-Dkb_nePO;O#2i$d`&=Pd!k:/;19e)Tg$Weq6;9-CMka#EW)W/e`e,hcsEbH7\;]tYbM:1L*b^D=$c^,7.Pup[/7?6&2K3NLr50cTe]R:Wm)8f'j!t)FDf,_dp]LI5W$o*KI\s:?=#WaR'g+V1:uVo)D%693WDie"-4@^YQZ$oCh.L1[jaJ.ZC)rg:olY:d',RkNV^jmd.d"NPs:&-GLY1PMo/imFMV>t9+Ss7Wr1Z-A"c6<,!Sa7VJgH$UMo][=#\>+,=[&ZVb=_d4="fB)5'ghR)Oe=RX;"0SEDCCK,)s]XBHdRA,bg=?(":igEn@Od-MK+aNPFZ9!Tc6"3c.2Ac2_+koEq:V:REAA:P`HG&)#U)W#,](GIEY=0/!HF]D@]B+(M;PUo^5<*2dnC>5Ok9-5*)nn,i^#r(G]@"k,u!@eWV[I`"f3u:35Y.I"HBhU>U%i`915^2g]O)&\q6+mA2?n1OO,.<&P7pJNB@STV**@m[sa.[9'ONAC1^UYXLG\t^GR!WD3kEBI?m2A2WBiB_W.kfn&KE#9+lPn*b'u%Br>GX=8W(`t:AM;&[7DXqM>fUd,ZIlnDO5n..OO@%W5%?=MKaBNs'CH/$gbj;uoc(;'Mp,\>)@l2V82UU8CF&>Apr?PaY1;^`<8QtO`afC(VnRdanT'P.m@mmDW2F)MBVf:Ob+!o)C1:&;9%6:1AaEOWodFaQ7`$iQfL:C.>YM,4WuD17]9]Q?;mMcdKkn=8Woa&'dLD9/:1W5.9i0@A'thq7.VDg,:(_$\pN:69LV/*q:&[K]IbC@nJ>/JHohds5qn<$_S)4IEm<dYM8&MC>gqGg>je@X3Wh.?DH.T\aDM7*B;A89G0=>7daGeqiZf-n$\j@#6(W1Gu+.AJF0*]>GDm)?SEH.*_=LWYY(t:AC;h_9rE]LdF+A6jDrQ^1k0InhL'UpK"6"o1_'FZ@E[qpZ1:"!Nj`(Ee)kg$(S4^h7dlQYD]IVtFH>fG\`PUL#%ckJpp[a<2MBA&)!)#)&<bfP&4*'AZ?+4=7(`r~>endstream
+endobj
+% 'R243': class PDFStream
+243 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2767 >>
+stream
+Gb!;eD0+IA&cSAir.k6tRE@Z1(9(@oTDY"n(YQN\jQg(::'Vsd$YPXL!Mg^sf68#R.8l=GfstARYnKbU!Bc9gG5#.dK,4H2pAZ6>3$,uRHOi4\``)@fX97K+S;lF?q;)$rq;^9@pce"fED5c2#Q%hINV-LmcgSaLgG_*m="`!8K3fA60mFbWgGhF"fOnJnZ=SOX/N!<N0`DO$J$Z3UCk$pf55`&'VXJ`C0:ME))OP:tP7s?VPlQ9p$'3T<apb'QdMYisbXEYP;M6`()Lg`T%M;KS1O^hsLq#1VJ4s>r!]roAp"1KiY*mr-r)*1`S+a7Xce>J<i)hKN#2H"nStmQ%c-?<9^"2U8f`&.1]\R&a*F5GXrAiKo')6hqaahk.)UK[3!cE'?'/5JlMEZm=<KkkL5j4H-6ZQ,iAti0`?.,)We.dKPqTjGHVO;EEhK(7Kh.tLs[@]mnOBNqb:/SU/EKl,[a`'I@nJq'm+p"B>a8kD7\/pV[+=t0AK"*<I$UhM-(1rTh#XX=?Bf4M*VZP)jU^0jLkeSj2"2Yf\'50Bl7`qOF7OsKo5=)6"N)8:-g7='`oM!S\eC,ISFZ[:Q@)JrbEoaIn]\6kJI`][da)t.c)-eAqKn,qjcJ^&+8f>`m\MMt-T`#SYn&*<VbR_1mnUV#NkU];9E_HBojj?EO6,403(I`S*B]mUHc_?=61:/[?jJ\.Y(n]^%<$Iek,p5/d^'A87]0ooA^FoEE,>5U-p6?UGRETe-P::+>9FD'&p*l*n4;&qtEluNMLbcn]ZM@bie?6)p*3C.BL0*Ad\@^;D-=hjcij]Vi8U1pm4I8<S!YD@(PU!W+`fHJL2g\p8/sOKY\Ne)6V^dSR4jA[c.=quQ>AtI"$GZGSJ)?e^4l6nF&HZgq\.r$a&kbi34F!W@j7Q^6,?3D(kX`0mfo"i9^^W@+r1LT,hX'WIG3A@o\G:V44%?PdT$CYOH+V,NYLMMJ)AH[6<-Gb'D_pkTqYD`=qOdQ7-9s,K#'8@:r7sD]blNhC'^a6>#2lsp9S1SE^N8%S[=NcM',gD?<g$4,pgJC$;&m7":`i\R^7'u@_lu_,@&<WF!Xn"G[USi?VtF#@pc]ne0g/Doh&-`9,='pb8/UAJZA8a0/(Mpt5X[q#.HNB\0l_W->a=eVjHnjoM^0!?kQds4ki:4dn?ar*qBX@<)0HVC2*AH9EleWo(!,/]o?[gjP^K<4/s7-S5?VD!/a9TB'BHOWa']i*n@@(>LeeCr<+<VeZ%QN"`"N8]HRNI,$9,Tk$11%QS!E_8r98I-kO$b=$H2<gJ.sM:BN1i2;=2YH)NpcoSdCGVL"-W3ROC[7+qmofo`;G7*,\VO-KG=USY7PK6&gNc-&N8fo7bPgk.dqA5K5e7!8>^3MI]K-K9:j[$iGaC1)NUR#sFRb>%\uR(#)iXAe?r:'uUlF_NB.SN$3pr;elt0>[Bds*1I+-bE6I562&NY)XdIg%*kbT8(0.%Tq"k4U+fKrkc679bprEZ2`Bp?dQ(5O"ueU;>;Q"Pe+l\]pd-Hi"X9o=NmFA;a+(*Qr:tUKZWMrBN(u==YSiPr54<?K.a?tXh2>J&FED>'-^S;@7P$&MW!NjRX0($jqfW"B_4>M41@-ua;92L]])E48B:l<Yd%DrK=u*`p#+S:RmSNOXC1FM.ITUa(&R&bo,#X<]$W^Q)IVKWo;STgQ--g37&D@'1kECu(#[kU!0Bi[1#+$eSY!hb5Zq#G`&rkFmdimQ0b1P5s8QfgDAjO*8Y"X?R4srXBXd?;nI\_#*]NnFoA`\`A((RbYbcj/F#t[Vkn*TXr1jM7"9i&UL<#/>%&a'9EVqKn\(>"e$IQ@<'.i@'Ej;*"jOoVhU4Vbaj4AQc)>\A,*;"/^^m^X9;krY&_<ot('YRUP)7.VT)]J.;&6&Y[jLKPW%rt(A1SmqN0^EZJ.c-IKg^.G!bUU9aq`LGa/GVQT&KGgC5Y=1/A?H)Yj-VGWhlHm*'"m4kN:M>Ys>rY!.g!'YA0.(luA[n)A89)D4IdB?^r6*r9L^D7;iCZ;bN^7s6_>JLs?7%O,;m.*QI+YA9<V'5B93%Kjg7!h4Z/pO;Lgtd'1fVJ))0$ZoXg4cAcnH#<E2TM)$;XMjW=m[;ID<!Y7g-+cZl64(koHt)f9^D2c:bEu<P&r)AJc4C$h8&6E=$k!9oSm=-h),'1$n<E>'-Lh]qKJ\g!Di+Z<Q0!Oo<NX9fgM);/J>`ZH2aNKE&nPPO0Q8NRjL0Y"(bk5@G.Cbn"qd[T(ln]P;Q&-#+;;Mh"`7^h&W'<ki,:ThnpL;H76@jGc7eR:5ZaWb-C+a\[2nP&,bb"kUF<frea8*t&7A^VL:YA=en8TifG2^^6)M&d!f34qX+2jmHd+?E;=o5E/e,iBQfki]2[5,ho^HCsPk+I<cIZRcc@4:Jer_7:#/dgXp<)c?%:$C)([3=J]*"0nE+[;AB5m1S=:kZIDU8k;#EF"U0=58;T.O/.%h',b7BscNk6RoOTMei/lqm9lB!'$F^F,qR&^l,gHB?Nf)rMh"86G'HF5lbWD2kH]/n9Vc]$tX1("BmbHn=p(e7C\@!C@#b/B8(fb?a+r"\/TP(pg55Zc'lPR+3"K&P=.m,:Y9N^M+!puGT<ARU-F?q8nn^@7`k,AaN#&NTh0%<r?7Jrh%>1dU"AWhIe#M8E:k5=><J\$)JIW]qBpPursY>1+4BDImPX4+BuG%\7s3ku-DfB:'#Rm"DP?(Gr[4`H(gBmcY<fgJDZpXhbr]RBBYX]H_m~>endstream
+endobj
+% 'R244': class PDFStream
+244 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2605 >>
+stream
+Gb!Sm>Ar7c'7CCQs"Ft3:^VJ8MPMX870,Jn>CW7cVid.:W;EeC=4/G.PtT9I^[KB!8PuoI;iY'-JIPt2fq$<S1M9`H=SQInT0Wm)152&ZgL(P"3X=DN/kdqVD#4(_htl*1*qrnV%%-MB4'U<R33qjcbdSR=i5*\0B=OttCuhqMd"?$@[a";"Y"q.UbbHaArKT%/2gPMR%l!rgn,AgUrk&0i\(ept"8>[D(_]B_EsB*JEpfCgM[2MDf.Z'qaH]G_QS,W&17cNX^kC$Z/mipb_sBO@hm+00gM?F%9:OSA68g0;)^FgbdCZi8?^jN.m1'B`eE`Qqku,<S8#:`X%L)k'h0&2bg"XXEeS>SU.WUq.i:>]7$8\CE.io)V9)ia7S>SA\Md"NrnKc=W)7!5HP>XjnWto8bcS!M'-YK!F3un&$`RZ(dgOAGGmYUOI^V^/%EV8VlibT:kafee7/l"-o;3]r$LX%8K&>[E?,R$M7ku\1)R2#H8ItsDJ,_Ut$Mio_]?iO1ZP)HllTh+i36(-oG6lkn@/if8V1)K_+)Xs[[.MOBNM!iCTSHfMqCW$/5e`kc+dir-Pffc,ule>m4PBZ1+Vb\8Zo@$3_o:T<r:Mt>k7-<Xd?_0JT^_m[8!$a?<Z*?7)dYP_^L<Of=f!Pc1*SA=4a'qfqW;eJ^n"mOF]!=?dKaG1]JuD);:h>rhH(e_A&c[!"H/V'1$U3U.a<SkP)423B*\8g*=br;%6=2p*F0=Fs*IM?BD?!Y8[*/WGqClf))9`"gcn_btT+5Jh!Psin8oH"COd\LaWh*oKdY!-)=LA-sg4r4J7"du@r/\&V,fjOt<-N'sL/RPEKL@e(,Q#`2)&6g'nCm(iPY!-b#&3)td\M]I$jfs^U7fUP>(]@Z+oPdW/'51XV(-`n`s0A+CXsB8hKZQ&$4bHqK=eX5R*,[B:@e$HTe!=p35[SJ&<b#D]9/]6]i:R7oV]9!JW-p+`7WhSBolQGi^c*9@328%B\[FAS1qD`M9%DA-/H3G1RQRB86#l+4'&jRre$;"<>,G:_NP0@Zg*Z>"Npr6B!I()@6hor#smkVZ9X)?2[H(h&,7p]3QDjGUkQl'?L0RL.Srd+AKpJV=P_/_keK^DU0VbC'bXo;d?g.7aRYRQ.Pt<pk2B1Wo4$P4?8^9]phX4"'75L$@:@FM3nDPD"PR8#Q@/b_S\`c@I0Ws$Do2]V8-)/8"JmTrfVBTX<)V5:$G@m3"/$BtmOl)GnY6Gfh-Op@A$1S="T+C$RJp[-@lAEf=)N5K8%4]fC?N0PZP4>4%4F'lAJdVIisHqk?cB&*>?K';(@aX;#aI`Q@&kbpJD+lT#eRSTQ6\6ph&k(0kj9p$8g7Os\<Mi/YskbkQ29=].J<+@]2hkceMnM;WI`V@eoX^!6?1`,c_u7(l<8b:-U/,a*mQ/1@:qC>F,-O<*O+03o>eR2bE*=EW_QH#B=jLTN#[KaZ/dF'&u.XnTst2[3LrqHmO8k-17ATI=!bb#gLWaM\Y-!6gY2f7\QS$i+ohsfJ4R5F#ScS5<PW`1jpCSb'"1EqaHXd5E`Hg'A8/u-N6FYbMOI72<=niYaC;+bb4PU$"55XOl]%>gX/&1:3)h3GOhj46P(#Y[hH(]B?,\]n;3e1U"EH*si4+\g1MCEb0)s9]V:L/+pOdEDWW,$nc)n7MMpA7li:YV7!pntU;jfKOLsTVI'C$JQWEOK++e0oKX4KNP.*!Dm<3>n&p0U&N\:(r/@+;Qrd6W]O>QjACc5cE+5>#=s'J`K3K%(TI:e!S!ogBVH)J^VT-l=Ki76LY03>":=f8!j8+"P9B+3@$.rf'c6q1b&$&[:R;h,?(N2>)B5fY'N+37c#GdF%0QJop`6C:a]pfO6BlKV%uj>nPGF?;W[0Bq[hVMkr\5XZ;c#O=$fu8!$ejpO7\SNf"\2..^00@oqFE5mBR>Ynbk5Sg61tA"a*RQ*N]XBl[Tpg)T1U\;Y*OCduHkBY6Z$7oIp!^8VqiV&*<8MjQ]d]\cC#\N"=^#:1/mnMoZ7k?-7D`)KZZ+lQPSJ"4J0q#F?Efpn9>#Gg\BX6BcaB7ZE![YLg.Zt-5-6rdB_>`?(&]J#%gR$E@p$*$5pk8H2LFtQ``XgtaQXP)[?Q/E-;flZpNC$hLO!=G@qa`o"02`.Q&230I/.+)%=':o.1/9OA*\[fg&gA2E3Q`fs'iX0CmG%']%4VVt*R+!.'NK/id2D&qja4/E#ZZQK$-HA1]gC,kWmGAhTGLF?_QX`e2<6:T;?K/g*=qmm.L:+9"H^u:$TnA#GIB9V1DDoe>m]()RMYJ\:AKNU#m/-4B>4u%`k,/=ZZq#T>O(5mT=&kY.ii)<hrfH3ao!:NX42BIArO%q?&gdE+L[X)@+8BsE1X?BbgrI1[@8qGo[B7gW&H0HN\_Tbb\oU`59^g3J)>6/g+QO1C;dhlWW/h,J*o/5"Cq+d0TdEF'0,DM^%;@.Gm@%Q+0<j8Amj.G3l)V@NEMgY*oRf-[2"/YbLr'6X?l?N4?@oPe3<#\DQnlJY3*PW(m@B#(jqBII_0Vd27XgP9I$`mW;4WPBM)=B;=QE2&84"?IZ>#Ll4_BkofnGT;.>-g0rW,51?K2~>endstream
+endobj
+% 'R245': class PDFStream
+245 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2902 >>
+stream
+Gau`UgN)&i&Uekgs.N(=CN!&U6%Tol09KbJf-u';?-0WVP_UD9,UWXIn-gEloC_A9_.>lg'Wa9`P3aBD\b)CUICab>_AIbhr]e[.?=1V=IL%*e_"AV_.#?gX"2)<rrp1$mL@t%="HuE]R,ORlo+93bk#no*:W(9_G0cf>WaWNe,$<-'E1K93#5B+gV]?SiN4'_tO4h=,MjJD]0=_"QGQ4(\^GI$]4u?j`:4nbMoIL8$JhU^K]U^^sP'6_t04*FeMZoS>G'R_JppfaNh1hiRr'oPB=G"\Q<+[m=V6TO[o@5_ro][8^P(:XJ:fOJp`T\H)YD'D?!U0em\9VM`GRMATS-j&."`6NP12@Ip4//oo-.@NSA?t!*r)d]=8_I#')fK&8rek[nbtAsZDC&Qeq7Qs:dW[H+iMC$:](]sR(_\C:\F_31A!i:/kn&_X_V$XtcTkW&44^qo9bj#!gF<=B+6U4g7)mr:&h!$F\ReU_rifCZ4G-=p>=l?re#L4J;Ija7-Ut->XKE!.37`opi-c(R7iBrnPLr_?H?+lKc;_mHc8brS.8h/6\WIuc#36tl[NPU4iFoIe)a)3LbJ0hJ\$GK#>bpOD7uT3oW3qLOW=Y:+XJunW+B*S>3^Zs]8UDgZW<cW`PL$hXD_9a8-p4P(Fb0E#-e!IKq!I<d$o&+5\?_sV(jH8oEJL<OIGmPFIM&,P5jra3@C7J1N*K"caFf;,a;m.Ffn`o3S&#QlLL+ZJ;WP)&_+DA&I;D=m]s5k7NRjRu#2dn4<b3`qVR,M%Ye/f_(aR$@&rjO5i6%$QpS6k^ZUnqr^R;DM[k$qJdXLA!EO`&^bN\Lao*rD3IZ86VO"1o6'6X,$ptT72+^Fe\c/@UGDT/IhFrYIm32<Yh-1Z(fjgn&EP1N\TPD;T,b.VkG0:k\J-J-^8UB*;,8%cBNkLGWc5(@eZGKQqk(7d]M%1:H.\3@2nDJGHPF.fKJes[SEQUW-T3?r?/^7dpPE71g"L_usAWC_tg4Z_ThN-U;:i%'?tX7@c]`,$2Qak'%gqe6<8KPK_0,QNckSQ<!o0]t/Q-9a#'c8%h^Q3]i+jECka%j\[3dtaCh-ZLL>dZ"hV^J#6X$>K#;?Xj;FOuK,V.ko>'b(reEO@D!iZ)m';hi[h%&l&76YYr%'`7F-eK@q]7e&p+eC^G!ud9!?5@U:@$X`DBQ1>F=B0USJ-cXAN!7J#X3^+[LBiaUl:0b9S.g)H6q282:/bQIWu11_b0paG.(_Pm=+DuO..UPhPP%^%58b?s*hJ!NG9c%7W946Jmd,C;4ON!bp6HO<hMX(MsLLS$,7<>=.H,,-3Un4'3tl5&7U.c[NCX-D]*c.g!A"h*-OP2[$h+lbKF1+hc_LCdXW#p`;_i?&K$Z^XYb764_iPSK55GL"un%OXe(S$Hi0mg6OZPUeL.)_(Bi&k8Cin?H*e-E>56.I3gVGFm^u$4D"Y7bLs^.O,lT8VGPl,JmR'P`SLG9;M*uf;/)-bd:fPQABU[bXIZF5.P$04`9.XD736FC(^ubWmeZ!m+,!rC78`B>YhfO@P/d`U*Mag^*8P,PK2,H2\M6a!1tk*^\:I[njEqTU*[QK,.aY3WpU@S<0WV9SWY@fGcf8%=!Q>)'mYjF[.C;1o(lDQ>O(ugTkF,.`$A2_l*Z(4Bh<F<E]IaHJm4c!j)+emr4^9q\4p9'p9u.Hjh<Hd7)[)k58B&+?$s("cC='G0t]Gm<0o!,d3lqe!W5qD)d1nRG"n^/UmLo0V3f:Z\7kKW1)TnL35lk?!'`()Q(,;mVG[*dE8&cEigPX--rAU;"U*Dc3G,1;+mV1n.?*Q/LS(GY/`V8L8roRR5US_f<<G1`-mWGl7H%'-CH<,cb:o3AB<%8k@<aG8JKIIU$CSesCUUdWOu\"9_3A5M$2>XIoVP*s1Y!M>*Rq!2GN$DOFS1uBK1MPsA;"O'gi^%<49dYWMotb?=?IL\*1FF7&9eFhG[O5-(T4IL*mM79\.W5`pZ1'YbT4,q@G=[\-+fSK-?;Kh%purZF%;/ebmP8Z1jMXI]F<`HS(e@Z9kRCO#J4i<QKK`9d;Gs5.aC,c7nh@"I`EG^\?F/g[3spA%joG,-'&d'V=_@mDsZgnhqHYPJrnEK.Vj;m@aQ]ZA;<3\7\J=-<Wsg\RTR_NFaXcWWE_J\DlO?kJL+\I=NWdaGN=^^o2AV![Z#&$ieK:WppCZ]"eVRO2nVsN,4lO$J%E7liRVH!1"\NoYU;5+pLr^4p2iD-VGtnNPO>,U6mI)]C7QslEl)6l3u(CYr6C:V]]2OBeLO>]/+:lTl\:(A;"eX&/q@^>\phZa3X$h5\kXVIpV3W,N'+@5\s;6Z,Kr9>D9;^n,,M@lXFqHd]Pp%P?=EW3SRQ(gSjP=E-FIJ2Pg5(S[a._1EYNK@=g&MFOV&E$;mjDjX4`h2U>.U>?/kPFN#_>0dp[!"6^^[t2.B?r)?u:*a*\!5^;+%t-!JAF%^87$*M0L5CJA=dSmp4AOAR7dAm_fA>Je#gpa.>JP^DKWVBU>W>!*]o<ts^r1Ac?T`>MU01lB`t?i0UZd^2I\C[Lq!qqg^BQh2?!;#4Mf<8Ut"HFEI`KIctQ>D2_(YW('RLklPbYP]V?LckQAC\0H6.k+.>&W^,'*;[\U5Pc/*q/kah0+J>To^QVeI`k!(:p!O@G]lX<j4`pFDjIYERmPZ+F8Jtb^";.MM'GX?:2XdP8bG]O9nV]=#iM8tV'0CnaVM?V_3)?_lsFXoFs'.ToW^<j@4;s(DQWLNL#50NoO&9j$Crgb`?ZKL;&27;^%JD@bspF`d^5R#/W;c31S3U#9!M4W2%T*cS.?`XAApe_leA>L2!<6Rl9PPPmrAK[@GOB/"05?'Zfn\dhVW*(%,_>2\&1L1Ij.qOq6U)$olUe;~>endstream
+endobj
+% 'R246': class PDFStream
+246 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2747 >>
+stream
+Gb!;egN)%.&q*PUrh7Lgj(ugWOeQa":Yn&mP8\(tM3ZfK>0d:=Jelo_^_!.QrV^mA,Xk>69OFZ/;Rr/!5bQNfFS>h"_[ukCpAZNCpr<Gbr21'S!/h!XcjO9%$1AY5?[]>3rG)*eKHTc]@sk3'm_bH"[s?H]a:H:pH2S(_op^Z4hJ=s%70^Kp@5lJ-.o*c4/NL1fMAnPJLMpSj5?Rj.0)qF>qmCnJD;Uf(FPboFa#nN=*s_a\^Yil>E=c9Enr-5ZN)3EiLG)^:&2Hl$QidFBjA!c%TNA5Q1&fsC_m?\/^g>8g&Zq_U]YHH70+s!Q7P&2qP_2T$i%.#I,/^,9bmi9B"X1-<kP3-7W;?2"1g]Rnj0mKt?re8m5J>\D^^RG(<?$biR\qXuKr2Bg?IC#JU%b\-cFd!>ei#Dfa%;_!'VI>s=IuE7E_F0#BfLMQTB3..gWnSb$]F&*O0FJ<W(^EqDm3Aa$,Q[[V'mWMnKq7/Q8XIt@l"j@&)JZVebq!BQ8jLTBGcf$N>]@ij<VUe3\2^k7&*m7b][C=M0Zt\eA.6NfNP3TY($3AjmiJ&-\Gp&o9=*#_j?YINGVqW#g!BrHl\Q?S_\T^JnQfh_Wd7.W"U<Qh"1JW"N^Cg0H*?>W$7WT1\V$(*l,'<[>T2?Kn0p?qG+*0TLWJn"[T)\/r`_Ki%U"T,i@Uo0eh($PK>E/W2_7=^E^CEJWOYibM1fD$C:4A.W,K7\F"&#X$Rq`7$6RgD';qWfkgHrn-%4,9")PZ*[>UcKcVcZdmj)?Bftk-(YAKYkLZm_pliL_&!:Tj&oK\HLC=5>DmF.MiTg4a4)]m#iU%6nLD.;G'+;kR.7P?_:eV`)f5BEH6Sj,P>*Xg'Rm1W`h!Dd_^M-38?E(eL@ZY5i-!1N.'U[aHCr7tYM8L)*n1A/cZ3XQaS4;cr$c*Llj=4-aY`\J[P0nnlRBa39JVU%#fg-+LQa[\r/*-FsgoSfP6Aq\5,_S0M8m_/Qj*2K*n,HK^N]jldCC^BaA=><S4T4Xdq2`j5*Lb8-*HkRHR3M0IP&rPQ7X_)L\VpnB@W3m:r!ee2Y^kJ#\';HXk`I?"=c\\DQF>;3MM+LS.-7R'W"5U%Q7FFJ=<fL3AI?W0aduF,=tFO#B/At\J=,a0_uWuK(,@<oB?^EsAgjkC'.%@TM%h07]<PPM%%:XpZ*B+R`Q9-pVr5.C)p<@nNnVtj%4LP"QL,#<;qrr[*[FL:s'B#$hFEc$fIrTiJsC1_V$3_Og^dF$e;R[!QjS5tP(\rcPE`l8m(a/=BcP9J,]^,;Imd;U:u#.i.LIW803<sFUd$`Fi8TaJD)j/GB\2j[G`D;=#81RIZ#e_%%4S=NMH-odeQ\%N-19>ZOSh>Cidg8j_=VJmR4PHL*]1<fc`lbF1a%'$mJH:K0>t`(V;rD4[36`&MtN*];R._1\Zn=ENG5j,Zp-_;)VE"3j[]cE42LFE>dks`>/_nr%pWl+#;/B\P6Z'b`uLB0c^3R:6S^O7+1SW8hi*c[&l#<8[V_A.$HcsA`!2?jb1M,#Ud8O[m80T9f#7u+O+usUc`+io-o2#FCMc@9WqA6hTEC'Ve(m?mIB*hD?F!eQk6,c]N\uUiW3_soPnt@n\s#9$`.R!oe[Z2'7.65R<#9Tr'k0a,FfB=^Xa?N^dGE(@l%L.V*''WoeUt6.am^,\XRc/<a2JW8HG_J+@9oEE5C9&i8&K:$5=?\\iAd8e/EYfBk,BV[5Oo)l%Nm0?5P#$<<2+`Bn<dT$rt\6[]#[I:rcV(lhTUI0&_)Ft"H.Cc-6]]#Y8%Pl/hg=^<YULL,%X$SiSe(6\I.1"Z(Lm]3?3@_amhOO^!YF1k-X#XPP96j?MdYK1<?Q/4mCbRe!k8Y)O2a-QoV?GX&GeDrDsfM?GGanK4+6mmXJ@]>[gthi0)bcnLQ>$G`D`>-?KCfB]K><%0)/#Nh'SPB>-=X2-@]o<6$TSi.slqD%H9(Cd7/bWag'pFs*.K]6]9gM=6^KT=K(U][nSQ>-:ZSR\B/InqWa9O$=^gEQcVa;2:6bj^1YX<*(I;h'LR.Jm+@?j\Vq-G?6&J*^f"sG7T"Pl23i95;UErA'rG*1:9_ib##sXlnQiC-ujG8N/Z5#Ph*Gf)-CMl[Sq`ao$3Ys.MF9"cbNpNqkHg?GoR39a@Pi[E=_?Hg;h<LfMge'L1a4-UFJc()dP)BW)m?@+dHV/gY5ei&lNB-QCliESlQ#IdHpb4K'0\Si0i$>b5O[<I_Rc0"-Y$(YD<>i:3U;U:V9t<4k14$]u0>*VS#=nY[ic]k4RuLqb:Od=@hWtUlmg7XabN`-h@T2!aeR6O7D;DgDG<Id4Mu(R"(QVpVXdni8AU9fEfCA)pa/FfEgYk2\5@Y)c%7Jh62V-bE=Fc"D(k':HXs#Sj4Jt\jOtd_kk&(_=FjRGM\;?L+`=%$>m(IT1T_.$'mKU@4jO>A`ce?133T/G;urm*XpH0jO[f%bq#+cA)A5Z],'^QM:**eo;F`m1mrT`q8(Dh1\l84FG>N+eG&"nhUimY!e'Nb*PhMhK]u=X^DXVfkJCP[&4?Zi0h?oT4sYcH[ZVi.r,D"Ns6tHd',N3*Md,8(iK9#n;,SB9Ye(`O7E1;`p/$pPJIU?p"h.??)FIj#[JR=(=4N>Lp,b`4G?`T<j6^DL-\8fIUReEaZIp8-+EVpQG:2c^DX62S\J-H5D$nRoI3"%,_0KNu:$KCA*W(JDgh%m.T2kB9]cV6dpQ%`M]RKO'-8H+L~>endstream
+endobj
+% 'R247': class PDFStream
+247 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 4322 >>
+stream
+Gb!;g?$DdJ(4Dg_k!/&a^!dP.JFVAg^H8o=1QA<]LVAieVbFq:(oNSpl`Z>%5^XSDC%1\1B2,Z)hF@fb9B&;u`28#)pA^V@OCq4,p<"P=99sAQGa:jcn&W]6YJ5Hts#ChMpPA-=F.[2NjUO:n7%#pAB9);A+2@eAUH3NdF"7ZHZHS-b=;7Y&TuOY)6^9S,>MPATa*C";J!9!/=S70Js1XDD5J#OlS\S^B+UQQ]B!rL,H5S`GjT`%O:MO;AiOhe+--j_dW3+8FMd5Vt1<JNU&s;@&[Z/Gj3_>P+*_Eo5D_M]I4aIPses8-sa3eSE(\(dO'9a]rVK!Ai8t'_5fo_1WYEi_4:Xf1F,#OelX?"&ebI9Qk?icG89tF]NA@LH6o:dMr]]]R1a]J#WNi_6r9p&]$/(%*>f5[8ZGY4^TMHmjjnE7D",`C]GP[A.7Hr!DE7=Gp=G0/m4h!UA+S0j_-$:Itr9>B;rd..:(:Menr_Q_qO[P_Dk2@1qf-+rd&-?5tY.Ykg]l_d;@(b2V7+DZcSL$i(+.;`e_LL.`!jICC;^'<FH(7cH\1%a<CmBdUbG-jKcjUWd+<g@K'"kt5-a$h/>j*\0_nmp8_OEH[u9Him9gNZ)gnpNgMj0Hc+Nc.O<8,0nel%n<\*c(S>D9[07\B?^hBQJ%]18^r_Q"1OUoX"tr3mV_C!"*n<m.B/]+gRjfK=5k7D<QggdC5L'RsS&O[,lIRl``pnNnA:0c-8GaNXH[[pQUaRX4(obPkTi+?W=_>S*X\]25f_M6]5$miFPdX430.-?=_:hTqUM\7`C7-.a>Bh@+sqIrCtCLN`LAGN`O<nl?5>^%#kVQSlQL2e4:hIE7V\13jH7#W/Xgu_iL_&.A.Eimh;XhSIA)hV`-[u;q,D.i\\B--r_q8k34?JG5=[2d!:3=KUY=#,4#*3=!!nOfS\ocl_VtR@%h\[E+$@iOKD\@rIG^4mJH.<[U"o`NYF;AM!*)8(0%LafEjkYGC::HB<qTW4kK,^;R;$tBGYUL=T\ct;;:GcPf7qYE9>H>P'XZinPJH2jnetMnp1lej>EDY%[U67-)p#6laa*7cWt5I1qLWN#F="nr*C[`I.f\#ZQ?f)WLNA;<F035WL%`b,3Yl>^m2aR)foCe3^8*hhE=)M\%FO:(C*KjR#Qn(AG"Pg/BiLr1.^Wl&)6ha1VLtpMgU_\?'Y%STjCDfDXn6@2!MSF00,ifloNhhl]-AK/CPoY=J6N8j>n_]6'p=Hfl(Yj?;3D19tjnOGAuBqW$6P-!/j'?89Y@$O-j5\KQ%ggL#:bbf4^]#K"7!O$nq;;h4i1`p?_J6-2DRjc#1!tT!Zf>ipu3s;\-*KlTMA.Xiu^;4L*!)>[2s6&DUS,d169\Q-,ibk0"F%8RrSh*d:'p38ZYJ:MG-!%S`&aqjVJTeQd-N%*dpt6Y)uQQW0MHo,;k$n2O(nG_`l<$br4MS$-cUZ6BhDiP;^YWdcDBa/jJtFKU):]7lr$ro2u&qe'NSG(?qVgI_%lnRNorG^"%GTD,\PdY#?>U:QZ6QIPVK8k8'ZM><TcJ6$NhLdkmlp.[06*]c.W1)q4]B4X&t9qRO#^i1+H:L8^^Eca[^X4]pa!Qpu9"]f$_"6:E73^)66i1[:aIDUIEN#sE$*^J15re&7P)jjnk4=%IqbF-cA3CHVS_rhRK)3,g-5n>LfnKql3`\9NG\b:O2<fZ#\_L5c?>p2C]p6"5!d+ahtW(<ZK[!@a+LY=299BtG25Va6`#BDN5-^u!6/mEgkHVe$e?bA68=q`8o334IP`b\1+oDaa30so-GnpVP,hsd5eBjT<%G]uS?`Pi=Y^Gr@9$Ecf]?bBkGMu5VuL)qqTaAqi3[K_V"F'IcGGgcoD-(C1hj)V\XGP6%Pq'l-D4E$fg5k*hY:@jb5Hgb_I3ha[?eq;`/\+Mj.2_?!?a\$jho1ufD9!"!N"-6s;dp:gK(JkiX=f.@b.0',6KJaU>Go=FO\VI2N"#S-fc"7j6f3\n,15nEPhNCZ[ELgc,;m5>PWREVlCSoCsE3;3][Lkmr!!WMZhqf7iHPT<Q*9QhfKpehdccFJ`PNQH>CY.cNk7R1L_G`X2#H.'[!VQ[cc!j/SR2So7H_<<C23K:(V<@/jl[n*GkO]eafD2>20RA19GIk>iqA51Rd(=s$*8(G_1>c]k/b[2s]ue'0Qoi<3)5%,bAq1M%T)hQ7N<XetJ(h0`8UL+(bEoEWAt=bl14./i,h[tkBB!a1UL!fP[`E@pfQVS<\NN@)%ML4f\QEfT05PE!kC[K8qU]Xm)-QhZ8XZ][#>*%]jN#bBQ*lZ%-1:6t@d8ljpL_nJj9_7!gW,IPjlsn91%Y"AUr0kcKN#W?G]mN(UMK^bb\$,(o.dTCdBl^2kG-.sg@+s,UMJdWjAW@AoliLp+atMbiG]`fiG]TbiG]IY_g<&I2t;nZpr(9j8*<_X2R/\A.$>0hRZCpFM2f^aI*YL;8K)A.'<^2IKp1uA"_W0on&2)!b4)gkoEcDLCd+:''(:5(LV5Hhd&&;;h7=+7&#ZjI_]S&L-NbfEjGJA2eN=m)o!S*f:i"SU<o>%BrEhF"%[*".a>p+uWlE=M;X1G!G`FEP*A[G[<ZJoI3U-P?nMMT2'&(])]E#Y^bD:(`eT"3a3+UKI]3P[nH^r@>\d4/[q$r#]iX;]_$9K(dmSt%rlDi^;oI>IuklO1N%8AJdGJU>CM]%QV4[n!ikY])1rnZLo-L:kF9SSLA"@nbW(%DeGp#7\YK+O:jadT4^r\:0S5fR@HU(S_S;q8iON786V\-t]'Jg>-O/:dplCsf0cHneSql#n2h<)_"C'eg2u6J.^2@te,4:$D7d<$C:jL8D0_&s"at#Z3H9PuWor9uEX(?Mf^c"b>lj[9c7oeek9JLap#E0nEM<Qqei?G_ZVTSCNXaCL]WiaX.orfNHWI%Hl60d-Fnn,NB]YdBO,n&%ETG<.^oU)^M(i)H>7*^VOriCMgVpB8B;6e.70`/#u"?gZCAHW$It7BsEbY.POOD&QR)6`U&TU0qC_^C2$n"$^6_@,f%J&*:BR;b("*4\Z?7PJJhad\5o?h2817m'*q^6QFM5]Ta8pH!`l6GY24i7#gNPS<i@=IhW1gFY-;&%4m]Lpe7Kf0A>G\L0KCm*Z%:h(bBL?Dm)B,[LCf^nknsp<$#GW13l06#(D[\:*5clMV.V2--EoLbklaZ*6s*.,.ZLV"Q,.L1I3=]8<cX/Z/V^#Wjk`>cR[P=E>r2$A0tq%oCbcocn[o%&&/:Be7RJo%\%i]0U9_[M.)tioQpOVK()RK<g>.`tTYH9)D=MI27TqeQX[`/l>#=lZi<WR$H<m`(&>G>4.ViE8fk/.4[(MIa,biF.=A6/IE@rj-@lfIFZ4%M4D2"KQbP7H",-(!^`Pek+dLCL+6#F&W4X8c6):MrO7Vj2Sdmpeqm)EO?It=X'8^Be,8B1?>$CtShR0\_mf`"42'.c9[@5/YS?RU#JV.Uu'->&N42rKspo%%kdWLV?=19QaQ$3PDl"*^jn+@IOG<:7Rh19/,DSO?Gf#E-^&!lK*m;<8iM-DLnVdn)rmHa&m);d-cH=&bhKX.@pq(g2C,(2T]B8&*L/3sWCOLX`Mj;?_`PC6i`a[`duOPqsaSqO4VldA)8]pnnFNWj!G'E>aG."A.1#b4oTZ\fhr\@@0foA<EgOIl3o=PHc![klaWpM>I!;(qMF>Rph[ZY[l.k9sC"P<>s\D=,+k7[S+2PIo?b,!V@VY#X;A"8(*&sf2_qjf/,%DD30"X'G.!RBI_1J!J)[B7+KX`G!Q02;a?/=TrG,F"@R&LX+l!VMV3AaF%/4d!O4tGi^j\Ce8S-W$GF0G.L8o%/03JQ+b<m,R'*=N=9j`jj9ieH2,2+T=A0i=(oF?J3YoSA@TJV5"'uj2jD+h-*-_N&f/,%TL"_k1?#p;X;)L2<J$>$M'c<f`G\[7d0nCi/9\8d`rkW%F=(%DuiMld.`Pe8jlZul'+[6O@C]V<cd#e'6N#sRR@`9CbDCBjr)bM'6n2`^]$E[4?94Nc"8q8jB<bs_mO<X$ZiYu_g7E(A`U(Xo2?8!/Q@tSMGMBic+Yc[_IdJ3\Z<)ZX>JZ+?@n^i]=pXZ"+MBW?r]72rs\-6VAcN=9G2W&i(2i>_^X5[FoWLP!'SnRnmf<IqJ5/scT\/@a\Z)=k0KdpgIDM6D6lj9b/To,:kRp\&eHg9m"W1rG4"rIe,g>.p$TYEu.0c.uD^p-D?**$18R8:H7YfGE:<qlPp(uX'QTB#3c+,^4`)rYjCh</9fJ7g*SNiW&(/C%AD$GP$!HuC_7op>[Z02eX2~>endstream
+endobj
+% 'R248': class PDFStream
+248 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2420 >>
+stream
+Gb"/(gMYb*&:H4YIi&;j+Ph0>e+[sVH:856*d@?)0=4,Oge+;5;Kf`\^GDZ2bHV^2D7W8q,">s51-%I<B'.=)5o9Qgq]D[8:T!XN"U!>.koA=u(r5c$4J1KFpVjgJq=nn/]j<B6ichi61H8gn[:%eWZec6op[@(@XPRV19L_C:VSH;a[rHiME?#C$bHC`k$TMb3#;H)]VSBb15If=3lHP*Ber74(>-+8Tqql9/g$].D2HIOl<e-1?`IIZ;cOp8+VNq9-,n+>,66_BmPD`8_AI()+2950!nYM=NUa!,Lk"8"@n?JgKKS!#h+uB<o@sX.SQ+88Y/.LO\D'q-\2%Qet70g[rCKq,hZ,Fs'DT=K`d>I7E/XZlu0jMn4%Aq3fV/9d@\SfQ2&79EcI)7@WWm]C1o43+b]!O(38]6de"ig*a_JR]s=.-=F8"GQ=aYZfK\[dtT1N<'Yh5AlNC3+(!=>"&kC=B2HncTL2pHX#0%MX2"Ag101=@QaPZ]/N2n:%_%$;PFOC,G>^ltT"pTK=-P-BfJ@Y\l-Y*IIL=K#tNu:TrbUP<bn9(Vo&TOpXC1;!CM_MtTX67mXn4'OJe%FrE'cK'Rp,+p3k/4ASR7d1HQiK5_LTcL-H@qUJZ.OUG@7-qHcPH/MH^%p;)!DfQ8IhnL@*,(G[V\jF8NkJ/ef,9a21"IG7,e+K/E\:;%i\]ROu(^(@Z:ieDF#agI90;[+Z;1$sK0Gn*?NVs`uET0oK\]4?k)oq,X4EcIA<VnrC^"+s@^/`TX]LG?R*11M1.06^AJ=PXi`$D[[$IBY;%r!Go7G!>99Z@<NH#)qq>Zd78WBs^+bd!kaXB*Hf@5FFD*m-"B()s8DAc.f)Lp+)%,Y]^RX03.e'3I3U#o4/26tqQM^f"iE@$.3F,-l.s+f90OkX&cjPbInoPGFCQh1>1SLcMf&q[bpTi"m,3f'U>tIjmep]'aE^`5b63KC:#D^+dVZ0<hg@bXa7Nd]OMt1]m+[R*]+2k&B$CbeU.Y;dZ\.63C8#Ohge_g&'Ca&*T$Cs5C<.is9ELP/tGZ2eS?hLNJg2"rj+pB737_7c><sfsQE];giNpn#N+">OL?4IFB=D6a<dM#tbW/8Ko=?5F2jHJ;N"5!Yl=t5YW@K.,W)tIHMA?2a*d/fS$CMTDq0]:%q'?4'KYiah!M/1=Re7<@4m-L]6B&-5pGmlX?)M<JHnYZ`HT08EFSRHmGPPX;S8"/kHWXis&HN,j33d6ZM;O@+%98!tKJpQ\i!K$V!3/mHngW*pq+L<@eg2<:@QK:k_W63qb]Do`hA)/6srKjM=!"iW%P'2o)l%j48LUdN%T49I?!SSrq0]c6`*>LO!;9m;kEr`&8o;GXbn?<V+j57k)*t:If=eSP>0Dd@lT?FNQ[L-BjE=Vk&n^=HOPW_$h>fT"Tm@GU8Q,#ZA&^]AR(4E7*SDSq!SOj<SAkIF>-sFJ^tQ-!4Gh>>W!\.sEP\[FZ[/<OT\BJY`lu04-\0+;Mc]47;eKGAQ_uCBVTpgbGe+Ro.4o3'=aZI'^Tmp+=mu8B)JA6M&9f6JfD+7dKgd%/[m@d3SCc-L!Cn'fAC+"1t>/%K%r%!H2f6NMU<UBuM<-6.MQIj)C>&b+L%._V18?a/ntk=\^poMM8&L_Ur&<W:D&Map(At6G(9"NkoTR>77l4\o0hO<flU`r>.6\2Us;]n:kR(f+Ms0e[0VN.RQr1RMp2[;r@#h.Kr6q1,4_6Am-*[,UZWi!lTI=69Kl6.peiIQ^"Ytqs3(=pF*W%[)gC<!mEN'[<sTgn-C<q($,8@T$7*H`<b)o[-)^a1AnE;Xqs:)+YRr?9!k(b[dQug(m7+9r]1Bd&s;Kbg%K;HU/7jV#\c11h\&B4+]Lsi-Y4/$FPA[l<?Q.5$@X&$2HHVkr\:/gAOM`s8p$hNO]kV+/]k2c3>rg_hN>M#"#J1`ilDiA\NAhB9W+760XJ<p(+B[!ZlH=0<TiOd0*XtP(t;]V4b(i8X51V<&tU!+V*YpZ#(8"]6/SD!o6k9IFn-^+b[t-:\_s*bai`YOnWSUZZ1POZAQThX0Y,?]0[]Ebe'Q+b0X9m#OtY`B720J'g>8Y&Es/Sf]Oej"j71hCmPau'QeGF!#/=:bQS+KuoXP:_`mRN%JVO0bIra0gb$cg3Br=Z=rBmo7Dg4f%g_gaSnU63#[F`lqUu.kn!`gI6Q+7I6hS7fbl&b&Xf.Qokf:Hn7k5Ya1"'fFIih\+;hr<#=Hi5%c#sT;_:0dgp=?#'ucjq;M@!;FVNa.dV[j]\ZbK1eE>UQN,VD6L?!D-D?S1)AE=e`8m##bK[VFg.ul*<C-`uZ8`nb>:-fOTB#N-Ca&\Q$HX/q`,,i\DQ[4aOWWY[":02\J&c`9qLmfj>0d:F8")bO3(3W;YN1f7`tOK_[!_0Z3j9rrJ0S1L0~>endstream
+endobj
+% 'R249': class PDFStream
+249 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3929 >>
+stream
+Gb!;f8U&t"&\e-*rs.>Race^/Xi[0(-An/.:2ERe*24FGDFi"aQSusO7eu_V!k<d*"[L,QG\fU*LT$2dmjh@gZH3/sg\gM_6HIJ3jMs2;YoRk+:MeAJaNXt\kF:),^@FL3-16,uENHq\S^);G>hJ^*.p0<ij-/ZXYJ@0o3!ua+l'%TifX:t,?lqN9QB*X7r-/-*c><4[Eq:flq'1+`RK*(ds5W]Z1kE?I\@7<F^n&+,QE+=[[UV<j2\89WXCW5J@6)8L/[X5g/?m21HX_!'@l_*AZC(P=96R\$m\2Zj?REYX`k2^HiCbh\A,1e6D-J6Y&9G3j,YE5793>@a^faj&O2"rWOCGuZAU-ki/L-VH-I8F2_)iECQY0+AL2BJGG3#g0rb@S]*Eu&.d@/)FbB^dCZ**X11U>ur.sH3=:=>OUnf3qLTCfJQqNg;>B<RLHG@A#`GZ&igR'%c+UC1_DFqF/i0J7&eK^g^6?b]3im5pV.SBtI8\>opU((8=W6*PVMPA?.@(&QY'/+'Cdhq*%dme.1Pk<.H\0QMO6QtFYnT`q-Z]A"EPm*b3jOalmk_BGBD_MW0%_\SdFU7*suins\6q0qS$#XCX)LMl,`_WV5E^JEIu!!KmTepB56!jS53NM;=4E2`#06WoSKjSI]iJ,+$e^]W%">X#P$]R'[cpN.LDkN$O,3KUQcVhC4]_=@uFL<L>OV?pIFBc7]m.5Olio9<eM!HHhQYdEreY?&e\0Jf:fcWWA\hgr0#=KCquJA.cJ;tO1gnRIkSAX8NqQ?1tU^trmjid3pK`\@I17KFK&#MGGtY#3!oJF!j:c^U<j+a][?)jW>AW7aKI=]4jdncEb']O`N3)**12,RrF9og*_XlXLVhk=+YgHSQa;i*3Vr=kZ766tGgmbOseu*Ir[ub0%/Y/*Y/!=*aue4NRg6!h=LG01Na$SE#,AV<`@:`>1C.\0^l0:"XNQ5JkF:)j8Q<cin/Hd3tko+;&R7[u6q!&=/ta!ZmBWh>XDZF_#ga^K%0J>3$^K2pW0JK]@A@%mY)%K/_BI%@5@l?E`Ko<59!0/B,%,G+gMpRtD_oGsU"A'W`^2!/363`ZjYU-PLM2'[ArD2g_*lpX-lB(E3aI9=0W]+G,hTdLpq+2ie,N^Hld?[LF>%9+"[<>9t$l'haJ=_<%Th=>TNL.!W"^lp8SB"McN&N&M1kNf(.#!S#-CW`s@Tfs(N=:Bp[CA7)^K<Vb$4Woo)eo[%THrI'/+NCggAJte>[ZD2[_XnOQpgPk&PB.7Z&8-uKAn1]VC_=J-(3$b&Y[bO@JjoUOT8/lg!1OKHGNW<B1g9[M[';!Q#Spfrh8d>m@k#g]Q/:oO?Ej\LTAIuR9+L'ea!JEZ1@Yfq?*&O(2Jn7$N:1Fd;nMf-3OMNb(aUXsKXe%6#ps>X+4=?M.r9uE<%?I@B\Y;*(Y@Ca8q\=t)/O1JUq@A9fBRTaG!(HBZ5<60Mi6->6*=gq%mi_dWCeLBEXB9T`g-WA:aJ[][[_p6\M@=5D'\3<saH&eoCa$.]q-)Fcb@DcQ'39"W9pMNEnOY1c6UcHunK,dFbi^OU0M,5Qih42j8`(s*g<"BQ5]J+Cqo]d"WRmPLpOmUq8YV_U/<.<&SKtK=2;d$##Q.r4YV&NCZGT<^BIYDW"]I]YZ">H0UTDTB]PN/#qmqi/T!j6[UG$j[?m82YZe[N4?]`Su&NK"L#bP_n"[6gMKCd4uYB\\IoVp];1(qV2qt5:Af5ZkoTKIY40'pplShD\!Rag/4C"ZhiKMN]Ir8Ng@f@UNfaDT;ALg3**%r/(XKW9i6V>0d`7/;l8`mY/n?G@1#9.oP0i_@tUh4>(8r,B*rq3K8jZQm[ng:(_HAI]a,OGTETeR_L*a;0bn"`FJPF_U4UlP!PgdKfK.VXSfd2p"X+9o`fQi)liY)e\899@\aj_Y9@)f]Uujcr*S(91p=X";&.#ODU,\W7]'gJ*_0fV(+G^W1>'8Q?IJLFrfID/bOj5o5P(LKVk;p\Hcc\W#d:YT^mB,*an3GbRhg1W'<,Y5+6\_3DGDIiRgFtI+cCOQA^c2*T^+QTj:A]RE5_n5^QhKBKM3pm<E98cM)&-<4n<*#1XfC;)eXJLk.B^`F8HTP@4"m_8ni_[+G#`*+&pYWRU0"Kl!qjld"^!FT.B"\8M9"\P9gq3j@B8+%VFfb4Gm!>\WruP#'%O6B\G.6NCF9DZg:T&un/5X?sS.W#E6.!Zq#qD`j[<s5N03hqMmOIQX]Z+I'?=*Thr,/l^Nnos/SNc5@UV2_R7ipKF:GQmK1j7N7`pDU1L8^Tk;_pJhE2#PMsG^15R.[PSKA&KOi\Z<$`n42fNY.aU</,Po1\it!\h.(9YB^X/3p5_;<.>gRm,f3QW1e*H3^N4dEArD#"6:Gc7]-b9ZZ$>R4qFa.L03=d\IXhZ`Lqj>l^rl<bd'C*mVPiF?SfKMr)Y+lk6`UA(-AM)"-R+)PH,4-qT>phIhNJKVg=<Fh]!tHpcb;6.=8"Fb!,b-/1;\I@gPd`=ki@I:*0L[)jI3TBM'&)5^0JR(r/9.)_csKu%aU?!*@iEW*Q738U$-I<0,9"i?'G-AT0JoN_/>4(M_cbtSUS6ig2UY))<JDch,q/0;Y9MpV6$]0W=ZB3SXMkcai@LZC6,HdaqT(SB4u(uh47rL0gNKBI,WpKCg0h*$Gl!4__cHF%&\428h"(r0_:-GI"S#5/e@XpQCVVsNl2Qjc2f:hh3Ht%M9IY2VJ3r-L@bf'-&fml!iD(HF&UZZc9SRX&`kJ>qmdq*Zo'Q&]R3$?(jN%[ZEP>k.H2>$7d/63$'3`Abe&Q"S='dGZ"odfc#ho=QTUR;[;teHLQ0FDi:K0M"npJ?EQ?cpqBAu$nl*/PYImNP<K!Qd&$HV1UnHWVZWb;6T)=VS)\Xa:]iDop?59?#/Y=Ts84[c9g\?o@U*_k:)^8MOQOB/9%42O.qTn1t&j)n6Um/(V[nY`-K'?_dV/M"1idZT=<\`5b`k#"EJ=6XqI,nm\9f3Oiu7g3U4V;DlO9[s&)B45Bo'r5u;IRdWu0oC(<I21HHoS;t>'PK[g-DV_JW^m1`$QXLeIOIMg3t\F`_nLUX99_&*8Wlp)kU>ZD7DfY98Ko'R3Z@kEd;XbRP)+jXNeT`W1`W3X,be_DUS1I4%7_><3Nt9_)l5gk0f:-QG<ls85\Zo:YK8@b#[o(^Q%%B[Y@a'J"Y*(VC)\/sI7e5K5rD5%_b*EdT2HSf:e_SMYgUqGVj)o\<0K^,XE6;k.AbuoK/Em7L3]O.BYM8/V#N'G+pfYLFQ><iV$J727%hs=qu5-I;S#+>8O@9hUS(C3%6pd<M.g#UB]rAe_\&n?+rXKC)Z#]HE.hthLk_1TL-DFj*,2Y>^re?LPQIH&.<E"L_O`uo<QSopB[g$aGoG9@ANspq9Gg0;cWB=16MaZK[#,3^YL9MJoH?G5()8r=V--CS6[R64.X8["Z]`aln>+`/PW"tc3$!Ap^8!#C%M*.9k@=(bbQMO5c%iFo&aAf#p+ShRm%@=k0WNM-9g`sV(s:AZj#X<l1^qF,Tj58dY1$!;6Z:`ub1/$&3j$mggr?IUUJ'/U^t6Mf,OT1S6:4&:]t#$3BnV^!*-2cO?:HfhY)b"ONa"kJVnId(d;#J!^c5m<Kq7qoED3PJdfJQp9b_d)Hc@eR7SF&W;`7M*C$ueWoGTG)OA=K!6DL@.a5cB8pn!S/DLg`0;65`BZr.74Nk#I#0;BHEJWFf8Na!0@g1"b_WteQ#FNUDh_A6ocHEE\UU/NthQ*j_`dVIso&=p*UY,K=nP[5l<L?OlH.5]1n"*g><WkVh2&%g`%HIBKF=2P:a1`ZqH_m5tHG7'BU7SmtW+YVDh!'"^",o9Ju69kctUS^k.0r6#rFFZ8a$7-Ke)F?[o>be/c;,h=%3"fS0am3%."g[)\]D~>endstream
+endobj
+% 'R250': class PDFStream
+250 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2421 >>
+stream
+Gb!SnCN%rc'`D>\s+/7X\jO\F00cmR5e"2>co"7-%n3bi""hnY(VN.-EP5_oHV$hqj2@6h(Mea.JPAuUH1'Y%k>H:j%t5Ms2bXMQGs\+;G)51Aac&2CouZ9=nnN4=j@9/1[X6pGf;4*"mb)8t8Csipkb.*!DEsM#:LI/"IaETTqZ3*1`,R21L@Oej!ug)BHhp7X8]U@nOicKknst7-Hi8:iI<^6c2?V!pD.h>mB_m/Pp$>7B>\?S00-G].#=DTs6JR$^%e4&Z'U/'X`Af+-3%\2&P2D.Y'9V?1:O$'I6=d&>@4!:%H'UoDSWb6B=is;o,K56J<Nn;h14i9c9[$.DmpX]3QBSe-N$i/Yl\dmBgEk0%=m4TDN#Ao&g/TO]:Pf_aE9L5og0o7J@h1`dX^LuXIJ*DOY?F3sjrcGl;0Yh:o;43IqFblrp5XID*V-+G1'ljm5B)mQ1?@_P\:/kNi:7ZjA#9sr&aR\,pP7$KJNbPsj"0/BZM^0P/A,S9Y/l1qp'FC2N2o8GA?6nN7ae@\+p*/1CkXhqKINY<*2A(IAOPWB'Jg=6kbU\P,*JdD:<CN[KLV8AMVV5L/k@cN(HNtN/<7%_FJr[Sd85O-,)&$bs4-l2!VAmo!IOmI#!sP&XG5uU$_8e\0[TF.8aVLqM8^9K.(q24(+s[M$ePuUHI)j^d';(TM]nb?:^,mVA2-K-98m)nB<7%"]-GW8*f2X4-Wcl)1g?j0j#i0=EK4O<GfDDoe:EI^YcO`iYF`-4Mq?#2[Z*p3U*gAm<\.E([AIo/F4:<-/465ZJ[";p]LIH)i;:DX;^%&Zlm4pL+T<?H#.,*MP##.5k_t3a-;bk3OF%Ja%+kCV!4rg6`A,H"GmdkC>7Z7l2qhaB^0+ujWQ4,4$8ROe;A9Kj*uiXV5p/$C!F@"n56IR`:'?GYFQ!9SQC*Fd7QDacXl8-J((<^2Z=<5[>!iX`.Cm[Nm^P"u087PY[NZYs5daoli!8Z:@uHT>or-Iln93N04B41u-`hhLgqnld6D;'oC5dFo9a$"KcbjZn+b:2%,d<]UGc(Um@.)O_=_@4Ce'!t7P'W9YLM71*i%@=+[-U1&#)"0RN%Y;2btTBO:/*]@9F:l1&C\nW3M(D]dfOoLZ!D$6lsaQL!(KYng*f_>n<t.0lbmC;CKQXN7n#2_[O*>ffe'9[dea2u':<lMfL.r4[m\c+C\)*7&s(abO8s$G@lSUq2n[?ADJ5fl,t@Y#lDe>F*>iTF=5Z.#*,$YC2jLU,[\,,Y/<7\gmGM8h%!D6%0]:B\":Ann@Ls<;Y.8$"[WJIcj\kgX`):W3!8kX7l%Hrp(^MHM2q:8WDK."3$Lf4bJ3c-sl\"+=4O.sf7N_fCXom1u+77;"-VuLXetVi'(K,qRe]JuDHd(.F25T3Z1:JkbrP5=+ceVT!Sfia?1/M&=&C4PrQX&JZ8&A8*9ah;@G=?82ikao`/4</`H;3m4f7!V0Fl*5D#hi@-a)]'f`<AiO14!cZjftfAg/#%6CsS4WB!`B!1-T-I]'q)jK`LLS<<&?Kpo:>e+0PEhe1D]q:N`d-RF\"="4%<^`3_(1-*RIAf%.t8EtX\)=Qd(qVXA$!V(IMI,"n'*N>4XrCoe.)llpQ.66X%Hp=9MK;;/FdhFWQ`8a\"a>0#J=!/Yk(hk@a!mgk3.#mY45dD,mr:Jh`U;/OrEW<tQM%:;gcYTrOJ(O3=ER[U/'U@r44T'Pa4iSun_Yf@8_>Xj*nU.DfOd_%+:C^S7m3_@&OOOCNK]]tm/b4)&/\#BA>R55.`f4J%,fU/BZa0!$4e>m[$,-FJG9*BrsVQs>V?(GcS)"\HN&\nCdYRf+O<eJlo3FC2uC`n#[,HUrgUo\,r,\#%uTj9lL7k2UJE#Jd(q&J*u0K3)U//K:3()2N3m(L+Bm#ctd0.dYn"*-oJ4rO0>nU0l+-@V`Zf`bu7s5a_2Xc/;^(sS3i3q)B%<SS#f#ApoQXcZ>Ilh5_k]?N8^JP-6#*B*Wt=iGHM*C*X_4G_q/<P5;!)hfRH<e5bI$P0f\]%.?NfR!./e^7;2E:s1M=!&c]0!I0Sgb(_I&CkG*A,Du^f],S"A5#+,5#c&pmp<;(0jh[9C:/rU=+6e:V&mSn\rTmAZ:#D2B@8h+BcS=Zjjd3sbsncYln*p%iUp1)l_p;Z85g4c*fgh>W7)jff*B8h[IW*:0Y=#ZY^<>/mo?DUS42I,lp__mc/@P6=_YIXUQ/EH@tM.;bo?*BlR.i1.*QNkr_A>cf=##'BQ%&DF_^JSeu*TOjK3_A@k3.EQ*Nf2Ya=W4kr1?A;BF%G(YW*Q/X!qn"R<oj'c"$eWbn4m:bo"nYW\"6_+RD.Xp"6d%?QKm^%&J-8fq5(WNQ'MG[#UR;][uF!hiIR`o2,:]X_^QO!GX!bkfTMY/6Zu4o#o+l077~>endstream
+endobj
+% 'R251': class PDFStream
+251 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2286 >>
+stream
+Gb!SmgN)%,&:MkuraF^LFC\K!,ua6$*BBHXS=>aT3cuMe&sCV'!!@aLr:f"N8Vr<FS+\gUh6Fs48R*$DGL'S45Tg"-s$+U+:8W""/:\jrko>9U)o2)'S5(.jqVj_*4a]5>0P'\bkNpt7?pA>mZ+(kZi=OS$+5s69Att`Q%Yla_+UAoK`q=&dQjmcQ^AftsfF*F0@/;fUJ+_R2pRa+`O8%O('*f-8.a@\j$]\=#FHC;i<\b7&c9>"#?pp]J"1Ju+BOaHi@)]HM^g%h.2t`qqZ&k4F=?4_tiYQf:Wue@/6A^s]n>-hD5D>B`IMu:ed5#9i<Xsm@,:n2AeQa_!j6*`A3Xo&8c*W`MCGqKeaS5pC#krL(pjDQ.8IqWtNVaPPIeV9rCS9P'q/@%Qk^'oIX?R[EN^fB*mBcR9XoLXrUUWcQCuB2@4CUY^;dC_CRi!:_86(nW]9pKuhr)PCB4V2go-+in"0MO(]7eRfdIu0_GdUX*BoY`qNC_rTY]h/,Ynr@p])(44@6:(:)uc#(cq;,kFk$BViSZ'Mr--J9r'tmO+hdau]\j)G+7GjqTpJC;0CFKd^OMGgI>>&p&X[>'&'l=^;@j=u=A5.j@N7ZuEX7`QE!P,Z),.1<[O\J/9;`Mal8a)<&"Z57PeA$HZ(A5RA.S\3[jnXrZOaq<dNFJB+<59j<J(.&;Tpq-EiBfhWS9b?PcgPMU:H3!91H[5+VHf%abGCORKoru0qbin$qKi?jbCm8[i\t<_3TdVjLi^B$RG1?'E\:`LKDdjj>2P%6;,h#5o%HJau4;5!Z(>^EtV&f1]1!%?@FkmImO].AFOSZdTti\m$u&m)aS7qb<Jt_-?e&^*!7#B"d4hMU)lA+;X!RsQB;d1&!u!2=<l#L[<9PNgnaRMrtrg44+fFV_YdbK7P9!l;(mmIXB`PtOm)q8O:kZIm!Oju,Wg*V3C=%<$7809aF`sXPO<s\L?sJsh\CqZ/igBVD+GV[fER;G![)j51;-.-o+kE^,/RCdRjr[XE<uh#>LscWo[tPu*S<1lqcrBebe$B65o`'ZSEhS%>2`8LbJ\(T1fdmBb^&3H^1dgZYVNlq/q`p755R_<Y^8s@0NjYjai]iGFf!XfL<+aa^5Pl!Au28ICirb8g8->=(/-hV;T;AeBR."fqTObSZ:#YXTo_n,,&"3m[(4;?DF^=-o^ESmgZt.C2Yg5+,p:r*,F4^%`=b_CQH4TgVX,u\f;hLQ#3PJ,dRD&,]1Pf-JsiR:"%UUqcF;V]MK7Q:]a['TqRH/?3XTf*lL$+%MAa(c/%MU_q(+/0kCc\h@#*>=Q`F-DTmnm)fO5S+R%eb1kT#$<9W4+84`Guj1$6X$#>5H[@"!ms;GQeaM$$K9<SO8bh!e8qEX#TXG*NHur3N:m,g4aS.kWV5TN9n.[m<bHJ;/eE$(T5=68E#$:7P2J6)Wm7OYq<=%djIPkr4OPk!!Pe<4B;6Oj[LI6Cr0Veka![@]J8C)nAR6r*o?SXV$m@/;//B+h<!6J068&og$$?[Frb!Aa0,'rn3`If\-]Y\IG781fE8U-Fau)OY8BM!\Z[nq(>p)da"i@WirjR,9qI-(0VD?5Ii_,78oroSfoqEd4=HK_H%[XE._Pm1L2mcRSO:ER>f^bH5,V5I*cq;Z.+Y%-d-DT<"):E%;!LA&]]^D-Y\7Cj=tiuh?^UAjtdoXG@@8amZ$ZFX:b,.FSFLkZLB3\\"h*W3Ts?nQMVLo:rt/W=`)I.@+%F\XO;GiaQU4Sf)?\#Jm6AF`-,M&fd6f7AIW(_s(Wn:JJAL%h#b7p9oQpQ=&(hY3NYi<8nWGnKrkEK7;;,d!\^?<7f$$B5!G2hP+@W*TD%3^jPB@7*Idk^rqL=@7f<nYoV*Odm[EPSm\K)/]i95:p[39[!h'38I1bF"R?SRJOR&-DdTohp?HQfh'.#!c=07=:gAI=,GU+S5k9p(!p>Gc-beFI/3^,X&QNFP0mcGH6X(8G8^>J/1bO/12nL`T5h:qfEb'l8e=0<!$6*@kcqDnZECtDj[I!14R2Dk3r3]&(p4If;+MFL\JT2LDu?:Kar[P'3^#VcW%ptY>K8^6#hF%N\2/j3C1c`l?A"nmT<VNg88kk0bJ;k=B7]?:uFp_MqG[(LQBN?b'7Z]A[mn+c`(pq3C?O^9c8He7U4^/\87^JnjTht1=!V6eT+&nQWRc%_<iH<=P]P''R<7tZTRi,6:3>%3#Wg_>"to_r***UILJa]VjBG7n@f<GId^6#%\<d?(.5<u.4\GEDH7^0RpeD7p.7+8l;QW!(*~>endstream
+endobj
+% 'R252': class PDFStream
+252 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2729 >>
+stream
+Gb!;eD/\/g')l41s+/fUk8nHB-,7O8qijaBG&bdMY2)/j2N*0Qka5RGF@ds]pXe:2.EPKK(HG2+35c(B]aTZPcTLe-j,lP'GkQ?K&G!"bq=2lXSknKAiXP.6bWh2uo@L1[fT2@`4rP'kVniYqWEo6hcRZ0GTKhrD&UAd&$ESR8633X97qA2&c_GFum,Ns(*T<00qkNRN`uDc:o0:=omrnN!mH7.4jl`Pu"TInH41fp>/3QF'b4YMckhLGL?sQ.7G&PgrXQ;pTc@.&ip;"dJI-"4D.DngmWQ<hPRnIeRiEm$i,9Du'YK_sG,s96.kjAnmUnUAVpjkETK/='i;h?jukh(7H-lr9?#ijKqj)GcI(hXF.N%AJ9=-WWi,\G$;3D6kk`GJo9n(O9).u@E7-<D:%F)l[b-OW[Y@E@J$`*b0N:SaeBBG#=N/CIbA*s@'UB5tRliFc7Y)jZ4i:-'o&_&,t)iqGbYXrro@lkM.TSH5H@[:CHLOt;U'f%)Ra?H47#7_fCFLO[:XKo%aAVecrtWNH2Yr1ZaNm8`JgO-bJC:n>c?B=%?)Y&5lKIQI?c^WGr2Ja<C!$Es3:G&uJeM&E),+u9d0J0o%a>6Kg4p]C?E3u20#_*^T3[58kNB*Nek9gT0&<(s*B6k\jadb'XtLllk=&VMdtItI`6+uVTH'"ri--R?'7Q8tn^Ym\kr83gTOW2R1;b&")oeg/]]`k?_u-bZc.qOEFZhAZXUO^9\Wm"e3`0i*%/nr;B*-ndW+aZ,TI(lnh*Se=q8\>JUU([.IM0f+@"ZeM,E5MC&4DpLl/P^:[<,**dRU'BdsQTH0UTGJl/-ZtmK#Hf1-0imLEjsUUhC2S&_>tUA9F4UH:hn?;]PZEn6ZBON)]/5K(64\pD(&I7li`pmMqYa3r>FVmLCEdAPGiXLm^&iFRh*@@&>.7#lBJQD3jDrVFK4fC8s&^laV00E@WG*s:><f#'i!VH&,sB5P@sFCWM+98TFeGc;-<;mRcJqf0VRf=TdO(:\5?@CA3gi^DE0+4=%0,^=Z=[9-Oo\C"kA$DCA=4lk6XeHe?bZN#mm0#AAV>3pQD>Wmk/b_4f,VsSb&Ea_U@l<Q>bN+1S`"Rg;TP"I,2Q-uFM>%"kdk=VW#%S:q3#<oGo$%@pP.^o"R9n(o'Z1OPRN.-*K>n?U!qBl\2aQj!oNOinle_!/MPdpNOKSB3/cf`3WRnMMC'ecGNPPiI-QpK`P8*dL085Qr+>!S]YelAiEBhCjH'^5..90gIRaG@fL,M:+G&qjQpdI/RBJ;CWN=6aZcpKgb=[\rOKI2&J?BMi;Z\LM<_,1<,hf[+(oq:b^rAYZ!F*UmJTBIDjO>g0ZEHU@^ucrsgtTG6QS`IG#?uj:]3dQi@bG&(i\>qeQ&Xi2=45sV>IP9]H#!s%a4$>>IHK-".*'5K^$Q@Z'bBDS.fOP>[ZW*#P-]*2FH^o+TRt,5ZUh>-U?&b/Nhn/=WW^`sDhlhP#kAc3/=b/7?rg1q#&1,kU<_>*WJmV--"eP,bJe.V"1W`gPa_DP3%ML?\i&DUoi_!qWef[NMdk]Y-0I#e&YO[_]Aud6ES,7#K?lHW+FJ/:7EBSej%fEA&ip^CAb;)URh<kKN[n!U5`9p4/,R0=D1-]Wr6]@CL^qA&bQcQ]\e2acjU>-m02Sla+k3[+>89id\/.&sC5kn*eqi"\q$Afi0_PI,b.'Ve/")hI%%nAX/na7YHpf,n98i14:2Q_Cg?;Rl"C!QRQ^K62\UjOTb/O:/Ui7X7[#>']&.;\B4]r5?@^R9b2n(3\<8EqM"(<2qLTlTK.?<7nfg:L(adg/a<O!j'`XV`*@fkVR.7\SIdqQ$lSU@]Oj`n^XMQeM_[^_@RFknc?4Y0`DH,kfQf?eggP_DNCY\c<T!3G*b#B]l>)k(V*[OKQ$BT0cSWr-RF>E?VcF,gBF[]mF4U9pIj%W)ll2Y@_');;>pTO]GJ.gQ?,*'9?jgVXdPD6?5P(@]sc;oX)aM!F.:\`D.?"SUb`(J)_UP&Thq;Z'07<2&KjP"V^Ue7')`-W&1BUQ`ScHlh[-0V1rVK];Z=0F]"sN3*gf.=T)d<Do5]Gab.V+UB5;D%bV#k`;]eG[0#uIs%#?U&?_@32XS[VM!]u?XBrTIEreJ2lQ7%9nOJh5XDAN@R/*0!pIN(3eV=f@tEeD-mkX56I&)Lo);GGNdJi)]S6h!`$M73E=4B5F.s\S.]B^eK!k:<>+nXZ;!_&H<G_p?C=07Ve#l-Q@3TU7%@2)'!<;uTYV9c$$gg7F:Ck`^0*P/_79G/QWP)s)rfMhl(<@KlF?HKFF"m"1l1D/KB';/1#*[nXJ?4b1`A6<N75lGJOnda`#kRj(-@.*pqNSY)S[J3n5GCZ.8&+6_D[@`Z)2AhWX:@WDc/.?*r,>LsU4J-eq%,I#*rlO*PXkN*&&dsVQ&75_79h$7Ol0c&-D</Dm\/hX$#cFg0,W*O,Zt5b5EP4Mk-@^.n,1:9mnT)@D3'^W!Z*^W'Y1>DLi+@fSBd3sL_P+j`W""WW?S+0Lh9lM7Ncj+_QMS2+U\aSZ-'<#BeqkRGuT%\DK^^BFFJ4P[e4Mgl#n&!Q!,mAB*9uEqi2!m_'``<^S1K$h4-TJbdWMV?8nBJ8"J7qlP%9,YCGoRZ/8[C1QM(1Q=T.-/=FjVQi'qCknOd'"WeFdF7Ug1B@*+7*=ma3h"4Ku32GVm-W4e$oba[\rLn^bPLm#;#A[!QrV~>endstream
+endobj
+% 'R253': class PDFStream
+253 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2810 >>
+stream
+Gb!#]gN)%.&q*PUrh4+6f%H3(Oh1"N*'9S4-=`+5bfnXMCC27/#nmkH!)g,rlaIfU.I(B3:1dG0?&;87dXCt6T*?9%)o"c7Dk$l69]>+!&Ae^MEsTBD(T-ZZCARk]BD3&T_g>[FU0u?c3IB(>3"O2F_4]TjUE46C5JpL=C84'Km.XnV65Tq%)V:l-#=4EZCqFVlJ?s4a!iCIao^?\p?eiujo#!,9edTDjd+"N]$k#Qk(cJVbP-7<u6)6$Q;m%mA$*>bks"KkXP-$aK$m]IDK2M:?!q[I1SnbS8[Uqk3RH0HDaHdf0EML#HV@ps%2g3/L*l&KI\=%6R)=F;N-&J:3BI6[4@`8tRZ\0\MAf4D.rK<RZ_[M<&V^nmr645]4QbY-hQ3c:rVRP@+<WfJ97&u"FV)-1m_G/:j^KFf6AOal$JXGd/Ud#:&_gmER[Z?6ml?o][Nl5V`9H1Fu[J7tRE=mbTAW.hm^hGf&*!@p%G=jsB?IGM+Bk?*<XI.+WbfVo2AlN2[ju`[nYh)##T(6k3oj6-!5qi"6,CKh1_a!>$3:&6$R9oJ#,c?8Mq=4=!]?A*r7)Sm8j]%DM%W\:1FI*s9BMLC[4PW<-e"42q5:U`G7^J_0`k>AcLukiTM^?*m7i-SU8Z%aHCW=aFmbEFo.$<YkFkFJlcZ1#;7`5QW"F$p[UIA)NmCp6,/M+K9(30df`B#BQh0(71V/^i_.D9Er3l@d?%lacED&oiOHS39(PjT1`\Bdi>O_rp<6W5N,:71rmMY)Y:TH?=a,@SseFo0)8EOfcgK@.Ij^E3jh"neWG&*i3t#+1<&?EGJmMu]GW$kT4k%ru`DqdC%"D"(L5ksNuucf[hQlV0&.l%654b^)]=(pl&E/MP/(MAnsN!m!VWrl^oF[qPC:)#g.Z0r#Y\k$jI:],Qka%p_tRY,JGGW5d%a0!c>kT_"+_N%2nBhu+,%>Q;m_gnNSg9/tn4aE$uLW;I-Z"8=oY)4SR3j[VAl7*.#ZQ<`U-:pJ4X$k)i!m5CML$n4`@5/H%<[.tJK]>EPYB@7_0.kO`O4M]e#i&_6!=%I:XM;;"&j.'HIjKu5!UAV+&8VO##'`<.OG'`i%eaLtfgRlOTrg6B_DoZe!:8iY"`<R7_^JBPh)4p1n`$Znc@l=Ch.IqIg7-=+C)+Oa0927,VHBp:Z$:V!5gH7OqhKKO%n\;`*<aoA"j#N$-N\1nJ-olV@cmSm0<R!+J$'.YL/l?RCA1Fi%X0g)IdrCR/QeSf#WR*k@"d;h_l[W.!VFpXIUqGFYj,9Is*sT0TTCrT\G<4Umr`d*%>U0AS<\1U;V9]C,+S87k<#,!>V?@Am9J001EOdPCPZuq_7a,feM?1`9Z#poU0cl"8=KSP$j]PmWMs>TfT!M_qFd8B7]cKsXNr>7!g5MrS6155:O0o=%gd?;'T\h"/Dd<GpUs-+&EX\dJMu$q;lUNo+9:@&Fr/MBGed2^Gh-H@9+#<p@^NB)Q.oC5(;2[g.I!Z4S=t>B%WrdmgSeEn^7X19ce`<8^50;"M/_qFISHZFj'UDXcB^(sVf>[Wnk@%22P'WA$@U:kX[/7A;h50ICgspf-6NAjuo@_[=6_^,nZirNZcm=@d3Dp_q'DCSZqXG!GDa(i!\.1p?;!HMNCJc)t\/OLC0aHZn<a&"1q?@+X#9R;0c^/PLbOXbue-LP9.sd[!Gp6;[\2VA2as*j^0$I-dO&Ei#IJA(&AVpYq\eg.6<%#QG9GQMgUVPC6j%=b+r"K[4(mgU"BZBH0$BL<_s,HK6NJis.$BMFr+6*[Nk,Xb*RBL%@[YoRYFB4__I"I`-nF6!C%R=.=04`?aNJ9@"0'\M3jBfog]7';KR0%aM$qEGd#<7786urUh+R0GOcQl3P-XinnFM@J4Ztllr&:@kqNYTamHYlUOT`0*:)0>]Oeb/h6k;.j%>?biio+j>d.sNp/V.l.:Iobs;cglRt_;7U6o+k-ifJg4bhs-bVlp$QeC@&mpE66]?5O<4(Z_&K.Y4EQ%QT)%hf^Z/SYARN_I<"q,$[<ElXuT_F[$;6Q<`+XZdt[#7NhV!lQ&>N/4J;<7X1aFL.E@Y?,Sq?UM/LO.Ip@\b2,XE.VHB<F2WR%g7>FfHC(uffO*L^il4%*acraP?fA:!8B!j+QVR`^!&42lN=A+m4Cr>d&k`Ngi@H"+njDSMi\\s)`U$Z0%EJ;X8ML(X?-.IO"Mp^)`=bVW'QpnQ-jm'R<]ui+ND^MU+12MA9>imJ6kD@$f;"\WJ%+0*sGLX"g;1+>iTh<6DN17-u*/-\foC)o4L:Pe$p.*020++G&V^R"hTO4mO^,b(\`$g-TDHnh[;;*6bF+_)%d/2N4oSX!'Xa%t-KuRL@;KJJsW*KeK;IUcK=&HS7PA3\Cp<KH2%d>T*JPpTq=JC``W[6bHbt7N\SN+Y-a9H+T<lA%]VgZ7Tq-.;ZY&=^i/at])^B/,c/C1>c<9u%krKY:.UkU\+]a(TA!(j.=BCY&<LhM:g>]]&T92e@Xnp2!6iMQ;0;k=j=4.*8`.8`RW<VN1e\krP\e?7.7-\!cAjr_j9'm5+:H(lk-m^ViY283q>^[=Ou^[7;-47ic4o6/KXYOIX@mVVj+Hcb-$HcbK=KC9g-c!1S\iO:VET%MMgiHC%_QY(Da3hpV+-YAUTI=KnV#_&NHs2==$oJM0:s/E%C]/J/D[>RaXkdA%AB@fd*[r5FZ-m$g8p?BtSa[./=?V^-$h".Il?LAI"LCJF#;=3DkHb9&-oj)a9;[dZ\d?;Y3C`gt/GAEL_pNPAO5CqWRM`ul&3N\%/B*^VLp-2MgcX-~>endstream
+endobj
+% 'R254': class PDFStream
+254 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2804 >>
+stream
+Gb!;e=``=e&q5%is$OQ'P*-rX4L/0qV-%o8>q9n=HFL?6q_/),ikthO`W27qn'aFP@fV*)W&UrfU`uKm]>*Ujl[]9nrd+Ds:'&(9_"eo[4<G=hn3SLU`ERT#Gkp?_rq!/K;$ao)9I$(VC%pQ0X4s/D)gHf7pFfn3Wa<$Ze<s#T=JXl#%X-n/[,]YmBM2G,k'(e(c+\bJDm9";DuYapqc#fXd[+PY9PSS4-1nY/DaNquXc.1t;U5bbdY.>^.AAoZ6`NQ7<4UXt&eVH:a:-q215jbg&1N)q59&%M8$Yg$"*!^oEhC/(eFC0`&hhfU<\d8-]u]Vl[IPhECKVuW8@0GG$7GSB=GmRpS>S8-(+[4f:nWus;-G#)MIHE7-0D"&UWMAQP7QMlWb!EkL@I#9NBH:jF*Xs6rZ*7h.0P66i!$9QWhTQM-FChFM88fWc2#WWNK(aGBE5oQ<Vq]-jlrg6`ZK$t-IHK,Jm^bHJ71)qpt3R1*N'R)!TWCtQU*#j3E'LLcHVUIp-KNGdCi7*-mZ_dh'BYKfodp9K[A'l?a2@8JAm5pMW,3m9MQVQ6n?QQK#lrID!%2R$RjXtNZ1Vf"j;gI9-!M'AE<o0EZ$+uVg;u=ocdW&;Cl7oifEH/h+_Fi$k9^Wa]<eBIpJZJbE`^G,QX=HauLulL+dsChSbg&&Ykt^8T$qR#dTE4;Lt*6Nq9M3f5^&qqg=^\;$IJT1+(3BHd+>hK`i;e2p8;UQGY<;=`[if%f,Z0EdhX"dCC\.QJbUl+4'L5bHP^%S:I^KSs'2Wd;EZ(W7OB;P\!C!?^CSPH,s7GM%#C!nq=8[@9iX:(^<)SO:VAaNISio-M0*JrqET\O:6I89WsnJ!3Y08JK&?`gebK/\)$)liq4QQ8@SJ=HSp%lAuF+Ib^,g\98ZhHHJMWFJYe,__e>*giR!NQa/1eSp1_(<aI_4$?oU!<]3@/:hX(:uHP\T5KgW2ZG3,U9\*F(1pF^k2f4O:jZ9(4OKnb62)32,K*INWCVLH!5Y-YDOcp+-C'SfaFb.G?lenNW>m`nrDi%h[jPM"@u/9D*^.m1.`n8uL%V]*)(AA28jpl7S4aV;`K2c)3XJ]pWAlql3t<dq1R2`r^6iX".VaV/oQHiaEGX[o[5>jOnQUX4'ohCbGW;l*ZYAfScX49Kfqpcc.`1M7bkm&3@+&U8%JC#DIV7[.RcC:rV3&L6<Z)O9lpW7'\uqjU%/#Rj[l;lXhpEKF!#ohe0/jZa&%OE%,q3LCA?R>D>N+]`Okn3huenN7OYf`^=\k:<.q%#%p.\C=teL#9k].g>t'"-'mfaKJjj1.Or[$N@^&1J7YMR9>BVjBJ4s%;+mOD6:8L:ViaIbsph@"`hI*1&5.Y)M&W!<bG%[Ob+U65mYT<5X+_;'Y,A#W:t<]W#l]PVH*XYk';MX/^?fa\]SK`#@l/N'=5V@Y0L1,$R0ijN#$6P?t,=\Vj\0\!@L9f8XC4>NY8pRDU+$X84%u%l%E$+Md(6l78oc;]\>4^Y8%sI9#ra6pa-*-V!H9C'M`8H?#OnWl+D%K6YpLE2AY+iA^;5LUOsbFPOP6$HQ4r^?+!U7%N@n4*$4RPJa3GKpt$>bm5SS`ae0T5n;?72XYGj"Y$hf4bVKYAW"*I]G?[o`!SMuhhH^&d/)O\WP?g?),>rHAW@/,5nLQt$NXq+[=:V'p8o/S,W\;uCJ&jMA\E><kI9Wu;VW>qq]e/s.-'jJMi!NSH]s7rIbWtNB$Q2UJ_@gi>[3lUs6783aSR+LH(\nQR7l>Bb2AIiL.;=CiBRtfhoUru).m;Y9r&K(,";</agai`X_-F`ldXLmY4Nai#']O3b+,jj[<<CsZ"e)a*B6tbeN/F^)6(*R*-&;5_GW8X@,KAsdDk,(RA:hW=F$P0"0J54_Q0FlD\%5..BS"\[7]FbfY:_n;c&B6iR<a.MJO@iGP=MQM*F377THZ%!j)-pZAm_]r2TJ$8`Z2ETjA4`#3r+&+-ZJ"'^ln[/Gu=F>>SQsge)^jJESQuL/!4Tif^C<2Pt0Z]+6tC,5pdH7-up^J4i_:US,AJOa.I]c/F\B(>Yq$7aQ[%rT^Fj[][!r0QPlJ[hN%O'E5FU*VX4lu;bX4RSs<65d[.&jd`d@bY-m\OSl/EN;\E_6[#,hF=2d>!=1ZmMigRtWhEA=!B[n[b/mabnBhTd`FH<>4+iIj50k`/L"$aqTUcnN&)DK.sjp63Q"<Be9XoJ%b65+3Hk<e^!anKNkF7J%o>3/(N7\IF*A/9;K^jUlfMLlpY_H7I9cP2rc+^,P^Nk%Ib5tJ7Eg2ab=h5;s<3P36]"LjEr[/uh"^>&g.%jISnIZF]MX6S,F/EC36+nK=6rrZeBA;JcAcE`&MX9kYU`:-h32p0k<!S!$`f`@D+-WQX@'l?(8QN)lCn[ul1DhUQKLGU`jH7PB]U?)5H:s44V2r/_1N'X#B>FELGlRtoCPI@8L!r$AWbUptYhXs*e[8s<k"s65pV2KZL)I4.[S/#Vl#C`W$_Eh90kRmFsa\W%ckp'RBk)MO[*'Yf%*H,bad,r!sl\FrK/*5$Gi4rJ+C[u,PJUK^e2a@<>rp=9F2+/goC1i-Bk'\@u)h)8X8Zr48HJ_()QhkZqPG,dJfHKMS5;-L/_`-UAG,'\Uo/2(m/>=UnkXH216*b9lC<^eZQdnCoWIumAqMUDY`t?F%:E'"eTK\(u+36O@$E\$a!-\2bBQ%&n6$$@5CoBN+N1"d7Bo!_2B<<eml<QOb`qF/%5K%q:<CAI_]CdieYc]KrKBg6&0@;gWAP1rcGH"B.0>)]&413AgD?~>endstream
+endobj
+% 'R255': class PDFStream
+255 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2377 >>
+stream
+Gb!#\>BAOW'7J2#rW=KC:.JnblJAGM8M?LR=/V<GSPIW=L]f"L,estar9<,5/3m*t/DG8"R7o`"6]f+Ofs>=8&[ESZK^S:gBC*5Fqtc)0Kb7Oc/0"n)[X--2?Tio4ao-ncl]X&]U0omq2b21]Fr<3aK%Y)W7MBtBr#'YegOj+SHob]:S:tC%AaE2?c@Q?C3HTbn%D)l^0A5Um>CGUns2FqaC4?!?e='MsI`.cJ2KXscO=BSmpF]^`%qd\2)VK8i8afeX8$=Zu9#[o?AYlKPKjk"n=g$E'f.30W9#Y"X/+%Mq2C2FJ^i[]L_Z*+ON5r1WL0;df<\VEkZI]&r(9oJb@1'+LWA_,bZ!O^dQ'>J3Z_GNObcTC;":kK\0?SLiVMcf5i]_75M]`H.+_C_p_Zk3FE!NlmHLCM0,[Df8=*mu4E[NZJ_599dYZ?H+.ta2G?^+aKpFk>l=Jbcj2RM6>H1C$>Io*&liTC;\"`FHKHt4ZgFT1ed:gX)qQq8$*<<<l2ngNja'fhI<h[&s&9>jTFGVLj,OUG_@LqpX.4ri4naGm2%JIar%4\MTUf\3X<e2_C$U.2260qm7HGNT%W)Wc,fZd'K:+9'CADd`V/Y=HEs7/`A.\#iJGcrclNPdOf;#A4--+R?GsLleBEN&Lb<9>OB?VFc!Y2j_ND"<GAF]j'rq&?s]N>:+?Q,[RrWl+Fou&;_'iS:;6[dh**534^U0$QX`/Q*C]nM:`rU:))rqA]QH%i=g+]/"VZ^&(ls3Q3/IM*)OL4HQ*AslY7t5'N3n#a!hOS-'(h!"EC`+R*!sJ+BKHbV0<jh!qsWHI^?^a4'?;er*kKeoLdTenEEJ:>I.dFn?pK9Q,<=o!<tPc8sFsT2g.Aq8.YK`*Q;hFZ8Q=>QdQe7V82n[1f1!N]9R@>!8a8Up4OE:7"t5f71.6[%EHr:?"o1JBKDT-r\&jPmGfrE@c8`.Ho\A,@DH46]R]Yb^cbm.+L8*0+mP+-4<+RCC",)JrSk"F5(BG31n=m3OH##]1aH"@L:;cV!cPNn1:DS1#)pH-g..fCT2W'WdgPSgH:[B!E'c%f=tSXHA:HSW]FD7FY;O(WjAEPM&,qd_*LE2;MFO#gK<>TDD!@/\?)^&E(la>]<_Fog4dCn;b\Uif&F#-Km4Cj-CXl;IJ6aIX,e(SArSW]bMpeik:Y.OD?TWgYPSYcZ7,>\UWD$sK4P3X@6(3tgg/;VF'V'iLWl3pIPc8&%I"WiTNk)-)AA4A!WdY:ch5;N=P\d0U%2QZ+G\Pq+iF'A[[Op(P'=)R>R0N8e2lV.cE\n1oI0pX1%HKE(/.m"nLN9Pg(f>B8IUZM)pe?_)8e_P_V]gVX4k_4FqaS4pY?^U$<uXL1aM6(MoF=h#TWSAg"Cdi#isZAug0l"<3_k=Z!]6.U';7DI<G!NYKJ;bgB`cdALAVUNi)COBWXYLA>QO/UO;UY'Oq/M?QIX!!ZDt&r::rZJ9:I6U3!s7!NTq0Z&Oi<\Q3"s!O`9Vk=k5M*[W42H#G]VrjZXBb\q*7:P)FS.Pr(L@\J.KP@ilP8+\Q8<D>Wc@h^20kW/%RU.<>@e.^nY-?=\((?EgHFUk*o-.<0Xt]+!u0\kSBB=>W`r.6^`kr!<KCTtUAOcs@llF()O=JNPEfR/4o*L*jTte<bLmX]p2be;!Z#"Osn6q"gdar.&U*M\+3c+1D+!WQm8IgT<^(GtQ=9objqT#!k34hKN9`Wl0U0q?&fGc$ic4^Xu25CWOgJJ@ag)L=Y\@'tSrahl9BA`;&:_V^XYr"H_%MC+D;`>%>54O&.fcN-\h^68)BV%4B8U)??!*JAuJmhtd8,Z`StZ^O+KQNo;7.Ucs:=E*R`J*7,fl1lQC-[,sph%UC2R\g"3Ic4pLmFicR<W!OKSmOUi6d:6;XbL[rGHO!i#K<hNqVCDo^NGbD_o[/rC^TPn*ZR1sWJGlRO3/jD.@F0Jo]^7*W[GFt.\o=ZnD2#&iQ=qAD@l-ZH.Tuca&OhW9On%hRBcQ$W9`bu>8NLa^g6H^18bZI10qP-<Vs:NUVnNp5*?)8l_]'F@C*)o8)b^g]46V,k`>4YY.dH0='j7&8Bnl<jUq7R3/(e).f^7)MEo0F,?$F*5'I/Zsl1("rb)o@MWScU*>hGRYS:YsF;=638hU07$e'4C><YmVD%pbuPXtIEU4Q.nigeJ+>I&J/ni)a1+oi%<9E%uW[E;nHmaq7AE#X*.:1&Xh:b^sj7L8R,fLSK,K+5qK)_]+'9O.pp(R*Ib=:8e!(V's+Eb!db^*HYi=ETJg!GQn&]R#=M,%-U4JqNcJ+#'bGLXh-S>c?LeecJ>n#b"AR'Kkm$N0pS[j\+VM4o&o&<1!OiAB.?=jI#'QEq6Rg95[?'p~>endstream
+endobj
+% 'R256': class PDFStream
+256 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2070 >>
+stream
+Gb!;f?$"^Z'RfFDs21D?1t_m_[]p9i9=!r,B:A3XkW\)sfE0RTQ7L(Nr;40jbVohTCM5a_)'[b^e^;pXk=TcgK-/_CNAH*c!W;cM"kSCC#i)T3Ku$9(2gG;dL\\O3j$=JDc\V^NB<BsC[Q?-`U5n\g!DHk8_H,J]8!27.!uPS,\dhbNqmshh$$;LSo+>IlpGs*Ep^Vp@9_Vo<pW*3PQVD6>2fq`3:Dec@q42EUhm1>r*&$q/CK00tHVn@?#HmOZ<nAn7/..gnlmH%))m7VP.aHQI##m)I/9jjP;U?eM?ai-+,H'kZL3!%7[Ggm$a01-b?p`h@B*D.KaASmIFpPQ';\W=TVe&1@`'iTl2'E<9r]gVqM.A@1JdQmfkJ0Si9AqX%"D8$gI=M4[k%4d`bKkZ"n:=@a^>&dH%F^SG-@sCG3feQPPrXas_\*<m'p!VI6`R#Jk)dpp(/rlfL;o<;k6e7t<2Smg'\Z:q(sW+c;!)*kU<I\ENrdKN]'F?.X%"'KH7nHCP3+6b[Am,4=cq,@bH)!XbAP&M%Y1@<6U@M)".k_pakMY[%qsX:5e:HB\TJ!j=2oh$[:M2V;l@?:F@5ANa'3$,!B/0@l+m*`CCr9aaMkZl[0&soi;lgjF8nf#a4g0\?fZ(G97^J[ZeoJUF!2skXa=8q,S58KZtE,/HsY^]#KI4BrglQb)j(jXqAP_))NRphhmlTp/CS4uL>:cn'6^*u2dm"iFLU!Vgf=M-q++3d+uUuTRXjDOjfPl@LTBJ'jd:0[loVB)1gWsD\*S&UG*3V/4:WB'"XV8!mW1S:/%";njAO\56s_YbJW(s5Kot;]JU)HT6Y`L7;G4W=BojJ=&NDR0/-o_/H#g@*Q01lj<c-4LquT2=XG*]t7"s-0,$&`E(/hW<_R"q`T,E/22R&&F@YUqs5WV0E9P=$D0F0^7&FPJCSY-qqHJ=Rqj$`hqY_UM=>dl\o%fVcoZ7tG@SP)E"oWZFF][5p0Z*Q/WEh+N`l,k^')V$pF\;(;Yi(Z]/BgqsjNEn1_?dO5?oJ%sF9CqiH6IjW@UY$L&bA.fqb!1%l<^faCrb_'%F1"jaQ>XIPfA.Bu`BPq*RpkcRW,1(?rOq0l&W/:=GU`;^5q8SikmT6nOS),mm@I(d1eSQ*8X[V_%9`JIoX8-g@HiO!:RECELm%r'hKS_6]ba9Ts&-[&1TMF;+U"$<YlIc29R$8()USU=F;3"-AOC8_n[U)4Nm].\,irMLNUauqpRV]WFtH=KP=/]G2%q=Dd*fc)H8Pr/4W6PBIb3df/ZH-o$d?31H'T5>\tDqup#jp;rSKKHhIt$91QH5H0Y7mb6`_-PCP(XeN-'8Mb'=&26hBm:iW.nO#gO5)JNl:e`"Iu9KTre7YdoEO"@TR]$XBd!M>jF&nbm.iSm>hkG8g_^Q6HlX8!A&70h]ZfP[lmHPEL0rJ6kV:YRq,M@K"?F"cXtn7#'h[<71gUe0,]mmr_FHI6jVf?Dh&V*?.^7Qqsca!`MYMP/[\H;5tDX5OaV4Ko9io%tG3Yf#bugC_Xa)\QP"E5.B=s0RhT)jYEt[^f4BDOjl?T';Va6YK$:S#o(:)5Otl3DFWO[Ms9>FLm7C\cuDjX2h)2aiH;i_jXWia&mNf]"A6Q&qPVMANhRf-UAH[A`:LGC4=#o=p:"D+P5(:d_X$upA%eXqLdt$T9gr<Lp`>PJ./I2CNt==1WN(-P_3-5^cbse'erBU@19J(eq3ACh!S$"nEkB$6ANn@.4reHdSD`T,_<J7iAqSu6iKc>,[qbfshIU\sq[`^G7GjQmOs)<+lH6nq4Qo/aN)hkZVA"\lBdANu)j=;uR[XM97We',@5P0Q$Z7\3hK%JW5/Yo0('I@S4<_6jY>h?VF$s?u`^snSj2:?Z`(Y*?+tmfYe(QA]CP(!12W`q)/uQk'rcCJJ\CAbX`MbYMr[^q_1M&18LlCGa$8GfOUS#N6j.%e>7d@gt.V*"OVW_&3B6&$:IWodU@Bn0lTN00uk(ZlkptAhh*;sA1(b?\,#Of$T<cI@d)X)q<$HA/o5m>Dl%*^&<H+i2dDhQ`GrWBM$(6n~>endstream
+endobj
+xref
+0 257
+0000000000 65535 f
+0000000113 00000 n
+0000000249 00000 n
+0000000455 00000 n
+0000012239 00000 n
+0000012426 00000 n
+0000012668 00000 n
+0000012897 00000 n
+0000013126 00000 n
+0000013355 00000 n
+0000013582 00000 n
+0000013810 00000 n
+0000014042 00000 n
+0000014274 00000 n
+0000014506 00000 n
+0000014737 00000 n
+0000014967 00000 n
+0000015199 00000 n
+0000015429 00000 n
+0000015661 00000 n
+0000015893 00000 n
+0000016123 00000 n
+0000016353 00000 n
+0000016585 00000 n
+0000016817 00000 n
+0000017048 00000 n
+0000017280 00000 n
+0000017510 00000 n
+0000017741 00000 n
+0000017971 00000 n
+0000018203 00000 n
+0000018435 00000 n
+0000018666 00000 n
+0000018898 00000 n
+0000019130 00000 n
+0000019361 00000 n
+0000019592 00000 n
+0000019824 00000 n
+0000020056 00000 n
+0000020288 00000 n
+0000020518 00000 n
+0000020749 00000 n
+0000020980 00000 n
+0000021212 00000 n
+0000021443 00000 n
+0000021675 00000 n
+0000021907 00000 n
+0000022120 00000 n
+0000022858 00000 n
+0000023089 00000 n
+0000023319 00000 n
+0000023549 00000 n
+0000023780 00000 n
+0000024010 00000 n
+0000024242 00000 n
+0000024473 00000 n
+0000024705 00000 n
+0000024937 00000 n
+0000025169 00000 n
+0000025401 00000 n
+0000025633 00000 n
+0000025864 00000 n
+0000026094 00000 n
+0000026324 00000 n
+0000026554 00000 n
+0000026783 00000 n
+0000027015 00000 n
+0000027246 00000 n
+0000027477 00000 n
+0000027692 00000 n
+0000028181 00000 n
+0000028416 00000 n
+0000028652 00000 n
+0000028887 00000 n
+0000029141 00000 n
+0000029409 00000 n
+0000029654 00000 n
+0000029926 00000 n
+0000030217 00000 n
+0000030494 00000 n
+0000030768 00000 n
+0000031049 00000 n
+0000031327 00000 n
+0000031622 00000 n
+0000031913 00000 n
+0000032194 00000 n
+0000032508 00000 n
+0000032796 00000 n
+0000033079 00000 n
+0000033366 00000 n
+0000033626 00000 n
+0000033906 00000 n
+0000034184 00000 n
+0000034474 00000 n
+0000034755 00000 n
+0000035051 00000 n
+0000035334 00000 n
+0000035612 00000 n
+0000036154 00000 n
+0000036443 00000 n
+0000036728 00000 n
+0000037021 00000 n
+0000037306 00000 n
+0000037604 00000 n
+0000037841 00000 n
+0000038062 00000 n
+0000038239 00000 n
+0000038460 00000 n
+0000038645 00000 n
+0000038863 00000 n
+0000039236 00000 n
+0000039509 00000 n
+0000039799 00000 n
+0000040021 00000 n
+0000040333 00000 n
+0000040573 00000 n
+0000040812 00000 n
+0000041034 00000 n
+0000041366 00000 n
+0000041605 00000 n
+0000041846 00000 n
+0000042079 00000 n
+0000042320 00000 n
+0000042560 00000 n
+0000042801 00000 n
+0000043025 00000 n
+0000043397 00000 n
+0000043637 00000 n
+0000043876 00000 n
+0000044112 00000 n
+0000044353 00000 n
+0000044593 00000 n
+0000044833 00000 n
+0000045058 00000 n
+0000045414 00000 n
+0000045688 00000 n
+0000045978 00000 n
+0000046215 00000 n
+0000046453 00000 n
+0000046691 00000 n
+0000046932 00000 n
+0000047157 00000 n
+0000047509 00000 n
+0000047749 00000 n
+0000047990 00000 n
+0000048229 00000 n
+0000048452 00000 n
+0000048794 00000 n
+0000049017 00000 n
+0000049329 00000 n
+0000049570 00000 n
+0000049811 00000 n
+0000050036 00000 n
+0000050368 00000 n
+0000050594 00000 n
+0000050906 00000 n
+0000051144 00000 n
+0000051383 00000 n
+0000051620 00000 n
+0000051843 00000 n
+0000052185 00000 n
+0000052419 00000 n
+0000052656 00000 n
+0000052962 00000 n
+0000053237 00000 n
+0000053379 00000 n
+0000053623 00000 n
+0000053752 00000 n
+0000053958 00000 n
+0000054115 00000 n
+0000054286 00000 n
+0000054454 00000 n
+0000054667 00000 n
+0000054838 00000 n
+0000055067 00000 n
+0000055226 00000 n
+0000055406 00000 n
+0000055590 00000 n
+0000055780 00000 n
+0000055962 00000 n
+0000056145 00000 n
+0000056312 00000 n
+0000056498 00000 n
+0000056722 00000 n
+0000056891 00000 n
+0000057060 00000 n
+0000057250 00000 n
+0000057426 00000 n
+0000057617 00000 n
+0000057836 00000 n
+0000057991 00000 n
+0000058168 00000 n
+0000058338 00000 n
+0000058508 00000 n
+0000058671 00000 n
+0000058863 00000 n
+0000059058 00000 n
+0000059287 00000 n
+0000059445 00000 n
+0000059622 00000 n
+0000059781 00000 n
+0000059969 00000 n
+0000060197 00000 n
+0000060395 00000 n
+0000060578 00000 n
+0000060757 00000 n
+0000060928 00000 n
+0000061098 00000 n
+0000061280 00000 n
+0000061460 00000 n
+0000061639 00000 n
+0000061804 00000 n
+0000061981 00000 n
+0000062167 00000 n
+0000062335 00000 n
+0000062512 00000 n
+0000062683 00000 n
+0000062850 00000 n
+0000063023 00000 n
+0000063205 00000 n
+0000063395 00000 n
+0000063551 00000 n
+0000063737 00000 n
+0000063972 00000 n
+0000064131 00000 n
+0000064320 00000 n
+0000064506 00000 n
+0000064686 00000 n
+0000064872 00000 n
+0000065052 00000 n
+0000065224 00000 n
+0000065448 00000 n
+0000065612 00000 n
+0000065800 00000 n
+0000065988 00000 n
+0000066201 00000 n
+0000066341 00000 n
+0000066640 00000 n
+0000068581 00000 n
+0000069671 00000 n
+0000073063 00000 n
+0000076143 00000 n
+0000079473 00000 n
+0000081897 00000 n
+0000084809 00000 n
+0000087559 00000 n
+0000090606 00000 n
+0000093498 00000 n
+0000097965 00000 n
+0000100530 00000 n
+0000104604 00000 n
+0000107170 00000 n
+0000109601 00000 n
+0000112475 00000 n
+0000115430 00000 n
+0000118379 00000 n
+0000120901 00000 n
+trailer
+<< /ID
+ % ReportLab generated PDF document -- digest (http://www.reportlab.com)
+ [(\022>\213\334V\233\247\366\264\322\211\021\001\252\337\213) (\022>\213\334V\233\247\366\264\322\211\021\001\252\337\213)]
+
+ /Info 165 0 R
+ /Root 164 0 R
+ /Size 257 >>
+startxref
+123088
+%%EOF
diff --git a/pdk/docs/compatibility/android-2.3-cdd.pdf b/pdk/docs/compatibility/android-2.3-cdd.pdf
new file mode 100644
index 0000000..eb77a7d
--- /dev/null
+++ b/pdk/docs/compatibility/android-2.3-cdd.pdf
@@ -0,0 +1,5223 @@
+%PDF-1.4
+% ReportLab Generated PDF document http://www.reportlab.com
+% 'BasicFonts': class PDFDictionary
+1 0 obj
+% The standard fonts dictionary
+<< /F1 2 0 R
+ /F2 4 0 R
+ /F3 131 0 R
+ /F4 133 0 R
+ /F5 145 0 R >>
+endobj
+% 'F1': class PDFType1Font
+2 0 obj
+% Font Helvetica
+<< /BaseFont /Helvetica
+ /Encoding /WinAnsiEncoding
+ /Name /F1
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'FormXob.c4c4c9f90f2c427799b277ddd57a9a5b': class PDFImageXObject
+3 0 obj
+<< /BitsPerComponent 8
+ /ColorSpace /DeviceRGB
+ /Filter [ /ASCII85Decode
+ /DCTDecode ]
+ /Height 49
+ /Length 11548
+ /Subtype /Image
+ /Type /XObject
+ /Width 369 >>
+stream
+s4IA0!"_al8O`[\!<<*#!!*'"s5F.Y8OGjP:f:(Y8PDPQ!<E0#"70H8E,5RU!!$kRFE18L66KB5=s+('!!3-/!"JuF!'"CsF)XEA:eUihzzzzzzp=93Ezdk,!IE,5LSzzzzzzzzzzz!"O$O=]te*!A"3N!#0'J=]te*!C-Vb!#/mE=]te*!E9%!!#0X!E-)'[!GDH5!#/pV@:T?<!IOkI!%`.i;F:Ea!N5tu!"NX@;F:Ea!Or+0!"NI;;F:Ea!QY6@!"O0^B64+R!S@AP!&/;$Bl3nN!XJc+!'"M#F(51M!^H_c!+]V]@r22G!i,er!;^PLDe&hJ"/#Vo!%;>rEc_9]"3:HB!$kZL=s*eFzS#-/c9N;&m!jGd0=s*eFz2.HUdTBcIW)6m:H=s*eFz--ZDi'@d'_[`)?O=s*eFzo@O$D!!!!"('ntn1GSq1!!!!"$b$*9"d]2go2bnl#:TWQrR_)LqmZV*rMBPp"53_T_"M8\EcqE_z!!*,F!!$MOEcqE_z!!*,F!!$MOEcqE_z!!*,F!!%1PB64+Rz!!*'"d<#?g!!!!"zd<#?g!!!!"zd<#?g!!!!"!!$nIBl3nNz!&+BQW.4jJ;ZHdt1dD$@W^$Oa-C4]4'&*Bd:d>!\<'UEb1G]"41G]"41G`QQF(51Mz!")7n+A>Tf0K(cgzzzzzzzzzzzzzzzzzzz!!$kPF^kCOz!"o83!"<aS:/:ii!"o83!9eBD:fIDp!"o83!9eKI;agZd!"o83!9e$/7S*R[!"o83!9ds%6q[L[!"o83!9e`B6V[U]!"o83!9e$87T'3d!"o83!9e0+8l,Kf!"o83!9e!3<Drkt!"o83!9eB<:eUih!"o83!9eBD6;dd`!"o83!9e!878j0d!"o83!9e`B<*'&"!"o83!9eHG;H3\s!"o83!9e3:92Y`i!"o83!9ds)6q%(U!"o83!9e<::.tWf!"o83!9e-=8Q5Zi!"o83!9aDR!)NY<!)*Ah!&FU/!&ag7!!$kQDe&hJz,4GR4-BJ3-!!'kS8:U[?zzz!!%+PG]Woc!!#B)E-ZJ<B4uB06#^dZALnrqDIY:M+>PW)3<9*<!'ittBk@>F9hbU;!!!!)!!.jh!!E9%!!*'"!#bh;!!!!#TE5)r!!!!"!!!%>TE>/s!!!!"!!!!Rzs4[N@!!30%!<E3&!<E3&!WiE)"9S],!WiN-"9Sc2"U5/8"U,&6#71Y?#7(P<"UGJA#RLeE$46tB$OdCM$jd7J$NJi\6NI5i!WiE)"Tni1$3gY<$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$47+I$4?gK!"fJ:0`c7r!?qLF&HMtG!WU(<*rl9A"T\W)!<E3$z!!!!"!WrQ/"pYD?$4HmP!4<@<!W`B*!X&T/"U"r.!!.KK!WrE*&Hrdj0gQ!W;.0\RE>10ZOeE%*6F"?A;UOtZ1LbBV#mqFa(`=5<-7:2j.Ps"@2`NfY6UX@47n?3D;cHat='/U/@q9._B4u!oF*)PJGBeCZK7nr5LPUeEP*;,qQC!u,R\HRQV5C/hWN*81['d?O\@K2f_o0O6a2lBFdaQ^rf%8R-g>V&OjQ5OekiqC&o(2MHp@n@XqZ"J6*ru?D!<E3%!<E3%!<<*"!!!!"!WrQ/"pYD?$4HmP!4<C=!W`?*"9Sc3"U"r.!<RHF!<N?8"9fr'"qj4!#@VTc+u4]T'LIqUZ,$_k1K*]W@WKj'(*k`q-1Mcg)&ahL-n-W'2E*TU3^Z;(7Rp!@8lJ\h<``C+>%;)SAnPdkC3+K>G'A1VH@gd&KnbA=M2II[Pa.Q$R$jD;USO``Vl6SpZEppG[^WcW]#)A'`Q#s>ai`&\eCE.%f\,!<j5f=akNM0qo(2MHp@n@XqZ#7L$j-M1!YGMH!'^J^eG-NC01u",nG`Ffa4e4cpM":c88PCn1>L,"M]>S:ok/CblnWoh&#FYmpsZ*f6h'8mIO]^cdki!c&P7/NgtMOeqa+M.%A^H91+Y[F`*5e<*0Mi!INs5)nE7bT"_o(ZnRPP2Nh[.g9G3_gNKo-lLr5u4W\?PoW5p3@jts8l?<$bImu"h-G_]Y9cn@#KZ+/=&hgW]6hUSBAOXXZQb5utFf-?0\bAC!hWk54??CH'+Xo;O,jZG?r;L%q4D\)X+`4lUfe,0a9]im!P8(?-k&mdiO\P%4N?n)n$Q%8b5Fp!n'):A!Ka'XdT$0Jnj:W*cqej&YZfjBR'Fe(>,CGj$GbqP,0%C8O#^@IG;jCJ**k\`QbG[BRlGD?)2bH'P!Mo.J7I.habPKfAp*E`N;/hl%*^`@[$cPM&TPC,dJ*Zp1[)*CitkYc-sl>I+ngHfO/M)V4C(nk#UJIB;1SYM_H:A!sdj,-^>D82D8Dl2B[R=?+S!,173r#XEH9g\0]*Zr/drfuTXdO0tuK)O\?6HlmA+5R1C$_NdeK?,m`.fH'T-XM&0?-thFr#p\uZgaIr8Zpk6)S!%tSk+OlB=:NoQP#<P2]:Wr2f="DrKb/,Hs9gg6Wro\]p?!I/9;=5l-Q5-Z-+3EN[-)A?ml.3+HLm^=5jbW]qG/T`EJmkoT+fW-h,o[rOd)oNn6P2=CTdF(LUlW7b[`':!8PYA<L,<_K!Qd4$>c/lfIC1APF]KP1DaBXi7%4.e$[]KU;Z<[db]32%;q>L"]b>JZ[uV==1hB9*0-'#9;<UJ:9A#k3q:d?OD68Hn^W!\u#+g/bYBLAZRMZD0h>MM%_$IUNI'E$j\(?NWGP4B3u0_qSMQI"n=4?iVB/9ID:Og%=j<7bA@^)R9b3iD:0%hP1do%p#`.@(VkB)$2ELUM*<9Vrk%0LCtK[W9<E)&G$2U_1Ft7L)CcLP2`<EVa0&A%[Y7.ZH'R9if!jdcZr'8(FbLN,5Qqj!5Qqj^kn4j[E2oZab]!RT-B\\/\V2Xfj]Ngj6R/@D<X4^P*C6NEHZ]A=<B7]^iTko40+?10fd<OX->571\j`2]`cCAdG81rWJW:1PC]=AIr!hV7'kr+(nHXkZ[FFl47[\$92t)PF@rNAdP!B&(al$d8WJeVjK9]&kMG6S-Uq)sd036duDVJI9FH,!&U:LOC<@p/JSfQC#Y;FKK?F%2Re)V+ugY6!ZZ<K?7(0+7)'=@8]k\Dn:.<lI(,!Wr,iWL1j>)SHGR+N%)B8=LT_/S.MS/gRl3N%hQ;c.V8'W3Q`G.!XMlL+:j/TbI53XR@&WT$,QBQmLC>2Hr(B/TVD9oN.T8J>?"EJ09*"l#0TalHI&S#^<a]_fm.i]oa^,D@!\!&Aso"6sZ5;O_]!9(CeE]'J*:O.qL]^aPq7!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!%=S!!9X82Hrf`t_7p8jN4`^a_VJg+@><Jio$8ff66IN^iE5Y9_ObP^)u^1+i/PZ._i7WSn4hD",-?@27R,t#BRf^t+8R0RpMUDk=_W=&e+ESsdPrA(as;]Y:a2Wf(]Y&2q=ZHV`7_U5ic=r$.QD0fGZ/h[C86u`hcVI5h$dMe.ZPt3a!^@8p4Mj1a/pu^o>;/G>?t>d$gS2=!TO]]X;OT1;mhAc,928sSepAkmHsDh_7h>/nA^aPm7159;`$;e>J+sodOE!EP"BTu,Ba&Hj!1#e>5>B$$2%e=DnL"f)d(A#e00Z]fJ`p[;H+^QO9lrs4U!t2'u\a@:0j+3`C3kH3h4`KQV)8[<i4s.h<b+-e^_)73f1j*lHKbGrX't@dnnS'ZIZZ1X&rTKiEkk+:*RgWbb0T>h\eV.f<K]lpo!'=L)pVaa8RC"/Z5>@P&12aXr75u`&!-"e/X%"8HYFP^\B3GKp;T;"RRl)[76bF?A([#?^V!d+CG^V%L,FN%maIXm=#!7-AgZ1qYJZ*oR^iK0cWR!R07Rl(qS,5:Cg&4+[/XqAD4AID)@]qrr>3(QT;sO2gZ=trX(aFE9GF>F/p&%"PlHP*o`C_*^/GQrr<N$:](TX]t<5,Xf[Z$T+,"-gS@]LK4mS@JNtOs,iF!3:ZGa^q\eWZ>X,Sc`!2,pJPDZd&_[g.*_Mp!"]P;n!"M'tkJgQ_]I#EfU&Cf(ou>P\KNBInc/%u6?YB;#F]1r&Ij:cYQi%O>iI8JC6)8:f):\;WXs?tNfbulGN0B4BJdS]\!<#"2V>PB/d@kppn8*P-f<i`%`1HcV+Lec4$V8G/a^`*o)tVB8*UCh^i1j<g:[n*DeJcjlEuqVr8bNV0)CHhPkXm;EYc5BUJ,)%,&,uX^Iae;s8M2N07hBYm:P@!^pknUD<s]4TKgc.eNBJ8!es=eTm$jO)Umo&TTCDC>"b4oYeUR'<.eKoq5IAaf5!9jc*<t*_a&0-u8TA6d(FCnW^,Al5-m_1)#UFE2-`m)]@:c;551&s#3mou1Mb1Ai`=`>SrS!iqgll)/r"=T%5PFU:Q*$!<$qAh:0uPuLb`FR;Hh6p5[uB>%P9$"5)iTe$SgnIfO0VUDk)4F];Jk*iWF*,DocW:=H_-Yqch=R3#Jf.r0+M`_(V5X+/0\#,Au_RRal'e9!#(!8!BbF^MW$-Oi1k`$P3!>NiV'Mj7DF*nF%%<%oa479jstZ9#OS@`Ho^`Xh[[:Pi![:3C)3Tshii9F._a`X'+qcq!?'g'jE@^Wq"OYiplFE1_`Q0JlJD[kdNZAf0Js7(VjKkP_u,&%Qt*LRGB>3b?8iO;Q!>@X'.bJK(s8,lUp/:1k)\/;DUmLhb=&rdC/qT`QJF*=T>qJ%SeTYgB7$h<)H:eC2B)7F['=t#gOhOJL6Hd=L$'ZuaMiDmlne1jZtO<j#rdV3%79(S!*>J2DW6ltm3"-\m&B%qP]f%crr=%1I08C<r0Y:_ra6Ybrf4Ri^[P"Eq')9*rJ`W5!9lAKD=+ZGhhs7;A8A2OgCMTXJp'jT;i5GjX/)6[D1+p"8u,be7Yci(4q8+X2ak.)o^-&]U\cU#CRCr*Ym)r(=3O&'mdg+2WS<TH#Eh4L!;?0<jm^U8Y6F]a(`$3%i;6-b`rXD*X5KSbmB&#]J'(-c&,Ps[rr>WeW;cj74'QM#!0=l)lu-9'@@DG9Q73Vj\soJu&_mplH("VW\@rm+T`l9*35lT[[_1+l.<g3t;,+M+HC%/"'S!r16#VM3TK)!?\BjfNA,&(ST>BD(r%?hSn:T#E']p@89=,!V%KJIr#oFe:#UCLj+E]Hmg"]`=T098oDXj+N#=).JN"mkiN,aaNVu@"XU)d1Q[]t4ba)to)!TAKCTuZ'rj^2@b'u]o$'4A%(ls+O0nS4ft&uO[Q_j]l=GJ;e"-W2`l]A2a;B:J@BpV.\3+hrRZ22'ML:hJ4Te0RS=6g$\$?rc;fbIIKG389C4UQEtijWp-6p$.&!f-Mg2DuTeb&+M%H^8Lu2d^Q(&J)qrA+8+oKo[bC:U;]6-%HV_;@iOPBdONH8[5o13n;jR#rmdA8!!hKQQ[l4;-0b9F`R*/ko\lXjLkqnd&*NBBPd$(!_dGA.k]8uHTH=a3oIks-rr<RAddABM?^&]gm77i0j@^.?4iod@:6gV3FoMH`;##87!+/WRkkH[ArOBW'gpMY.qR$8&dHOu'G?YZ:Tu<1po$_Q:4lmC5Qa+2fT3K8oVtP%O[>LGj9Zm<nIQL3m&&U;t%fZOf(t=K-)F>b,[5<HnAcsSRStM@o#GN.(^'B%8n?9m%>uL:3)K"TAl$$nVMoAM'7KfKGUuOO@+S>E*rl`(IDr)6/!3fB$!9d-`62pofgn#1UGd?5P?Sh(-N)OrFNO"N'e)%bXUGC*blBr[pX^tBiRWTU>MGDQs#sp-!bBl1\[sa-mUq%.cT$?fCj0+19"6anhmtpB`m[!_E>K729WGjOoTB78)5j=f%5j=Fn81'5V'Y&k+,`3HY(s!pG^2X)PJre"jn99V]1'$^@bX)ub!\on"`-u10LX?&$j9oW#!+)r1!9bW@O"AQGGciO?0GA6T:lQ8328%rs/&&\[$]LRRj4_JPn1PZ.hu3cJVi(-h$q&s4<q#oHnk3W+'#tiOOc$DD,b/BbB9G!23`j&Ib[7X2XgGjMJ&GR%/^^DPk2\rU-nKqPh`*d*Jb`@X(M4Q8%"89\QW@'sM4BcnJt8-9c*OnDl7.s[Bgpb<^5r9o"VpfLH)S]!XEZC"ZaY+qh((u[QgRfa80.5akRDklNd`AN5N2?ek4k(Bl6WgYiCP8@Fn6N"pt2j1NQ&@8EX"NL!(c\,paA"rXM4liY3!,^Q7[C`'SSh`#!$aWgGg)I$KchP+8IYK"TJJRY)iS_Uh77X]L0V_%.c#.0!oUS_pMIm/k$4TeXTQPV"NUDHKbo\LGEc@7oAdQp>+/G-@!PZ_B'He;m'@ge]OX\NuJ?L/V>U)E1o`mai>7C>PP])D1"><>N4Cu"im?P)R\[jm(IaTOi8!o3s.4\0[D]q*Aa4:h>@Jc\$YoRi<ZQ&dPX3+Z#[+B:g'G\@tEF?,bF(\?6/nqg=o@!@/NR*RbB]`/%nKlm!t<Irr<:<m?,F(GcZB1@5+&W5M%,0pt;j#fgaKOaj"B2m3d@br/`j7,d47*m!mrg?Opb]N\*W63kQ$1@S*>\.7t+V\Jb>2g@]rPrWpo#*^@V:X_h90>:$jRaH3luNK'E/Y3%:8!Pumo`Gm!.`MK]Wm+LA)Xt?E2i0)AV*RHO#c.kt&8a(?0%$&P%HLid)1H54FT2$rj3.uAQ!+3a'\aL/Mr];'O``J0Hd_a0>$%"O)bt5s@W4-nlIIHA>o7Lbhl#U1srX([D'Y&:lpj&r4&7QlI8`G_sHBeWnl'#C3_9^k/_4MPAGAZ7GD[L4tIF[\))d-d8,Xu<3+]Gk4ntR3%A%d"lZP6SB?N@_iFElbHharg(0E;-?r`TtqXh6Q?o3O7_dj"elJrs7H/Kms4,>KB$4O^0!\@+VXSkjb,Y%jA[)!/-qb\_`TC=C/PUBs4aN,5NZm3LG0>$fCeOE4B^.rTcV4ceX$m1\E=J@7A!G`iH8]?C0Q!+W7=<A)+-QZC"I>`^b`,k)9R1O]K+dd_^.eSZs\Itmg-NLdE[jOGk')?BR58!/b8aZ(/#E]_m@Ib#:cpV4,&_eV?WFI!eWYXr;d""U@c+KGU\"EB'$9OH[\BpLR?HA(Su(@\];b2!XD&kVp"9mm4OO3[?'-H7^?.Tfq$iuUVlh!YCngtTJam'c;n[-&p">nQ&04T3".)>HS;[ltbZ]JlhTVTre.H`6X()0In^2]^*C"D!)4N/hW0&,uWJItiD.nO9X92.$l/)F;')@=n(/j,t^33!)DP-jd]FJd-M9afK9]pa@Y"l?=rW)rQaQX4b;`>GHXVEXm%l1kn`8_8]ZkDt]dtorS('eb"^k08AlQ\[9F_`m[Q.:G?At43VA]WD3XW-'!8SJBg.S!#(^9Ge>A=*(MQFW@Tm$)(o\]Wj_V&f'`7Y``8OO;SU<M$faasmfn.JnDo$@nSu($Y%9=jg"IQ_B5fVGOoPK),k7#HO:REP!5lji(&n8%hc9[V^ppDBr"MF0D-Oe08thC8DhG%M&\?Gpk?g\oeeV'?Heg:?i\o%i,Y$\7)[^C+DVgc$)"b#<`8`hP2rZrK%g.`M)P.O>\*fMO-TH24gK(c:?dR33P+,%sa3XbcnF>rMrrCG*eN`OU3p?PYrnP6tIO"Wnf>4qB*i#Oe?d>n.bA^?]UlgZP)3j5cM#_K\-^$!Grr@Xi=P8`Cpm4koZ2L?Q_\&MKhln7cF4V9Tig9A]Yd0&E^V`3(.nJ6:od!,+;urOjjpe#FHu<bHACo)ao?K4k_Xog>XtgZDV&RkV;-HSiZhW!ErH;Q2$?]?+2UA3JU5JoRl9'"Yh"Y=;mtmYDmA'/_R.o39AuN1:=i)s?Z$C5HjcAD/=<40"1QH]B<f-]\r-6Z^HX/R-rL1,UM='5'jde!k@1j:lh6Y3bF,lYGoZ\-@\X*Z`/*@X'*!S<GC6`9Gbp^GD>drg<P0p=u8t0k`:<*V/1ZD3KYDIRBf!48MKlVEMh+A%UEH9''N9>18Z7@DcQN[!-)9%"%i*BFEa6]5SD\;2qHlfrPm'TK[,Zbc4nsJJDca$+'NEBSiS=pf**=d/`m1f.5'ua\I@;#8d`ta>LEN@7j^3+-;)^sFk92-&Mmnf9-daqHGL%0fT:WNJ8g1*XYphOC/%oLd&[04"&BeAHiPmj_)8J)Rl)p'D>\K1VRp:g<?ip4qD_o&&VnD9"EX53#$NJ^t2Vcu"%<@qd<\4$RW/BU#'&?gJU\<d:YphXJ\\@L1mMLpJMN+:$Jh5$d1[sJ%B[_7sT]=lF<LUqWjOl.5j8^q-&>[$@bd*E:a.-hMH&&<g(/,Lf@"3/%lq!7G`=RcoVD_19&^6*:#DBUa1jfTWUb@C:dg`3I^"`oW]r<5W<"tq+:iph7CmVP'2D(Rp:_j=`V6JN5gp,k;-oC-[Ur+5BL8@@rRLMo%!@FpUa'pK.`W+_u'9!1oJ&2VdtlWN,SoFfo+!RRsG>WdHZ[9"6k#dh)G^4WUArN:S\pnQk._T9AOi;Wd'YH7D1Y9SX5"Cbc<,\9=a!Q;U\rpDl"c>d2#e>\brR&hqu9%]SOO!7s&me4+jg3\*Z\J69`RbaQ<i,@?lj#sSu[*(FYB=lts+L7"Qe88^*<4Gp/6\)Eqj:6-"c?aT7?eJ)fh\3Xgn[$.u+$Lfl8pq=(7bUhN[CLj]B6bL7D+>P&.S'5h)'i_*I0&;$2I.9=g2<$88rm\a_[E2K$<7.h1#%T#:G:Z(_H$)jo.5:TX?EBs3'o&eQH?S%1U[(kpNt\T.:"qqf_J=^g2Fsfg#)Lkf7#1DGN!trM"LXcAb%.!#p`?QZ:MlT@>o*,KmmIQk8eRepoXEYI!#/*i*4N^[bnEOX(hO2@nA!_QSYjGFaoZM8cd'E8\c5?O0!#rWph>e;oE,6\W#c]X3,<Zq&o\;M=Dl=\ZGL1^CYKnWCo^+J&?bjhBhYMm%aR\$L:Tuo/0P;p$d<AIUXUqcB(FKeU`r<*"i`;?=3R@C4@-!-Be9dPMm8#3`X1spXd"-W3Y(^!KK!J5fnj%&Z-7`P&l2qqLXUtC2f.\j01M%4aBq-3.!KFMro_fXP6Nn)`EuY=mB(peMQt`IIWYSHu!g#G%a&l[d_9&RSqcCI7YP.":G@2gSF_H6P)/=&'V\,1;C9,_]O\\hQu1%ME_UC)>-X^$=i8PgHoM78<G0W`,"s(goMG83:2kmJYJnQ_,r6`?&c]nXHLP&p:")8-180YkrAA"mH,cf1tQg2aa\-QNi(Km&)!.D=c-WuBPs5*A#Wf`&i88elW_-.cbb/NGQYjpmu"c#Us5gmlh=5CXKIc1Pu8bKhW`QL1s@kd&'LIC7Xa#J;S_dn17iDS0[)9#`6Nt$,&r8M>h:O!]!^!]5uW0ddW_tfn*I79*uT<-j4D4T:LEVAjfP?1d]Kq4p?`hum^[O?)_`5I;B$jc)='bei%GuJ!5j9<GgUmpHJ1ZhBb$rIlsNX@A;#R^2M8Z@gRS2ZNbdi..FR.e*A"Z/K2lL+6Fs=kQYfJqjaLP/]Cc\F\Phe^I/EePp]nff/GOqgrr>pca+j%?#bf`nNo@)lg/.nB@:3Ug@6k7`,ie!)9'j</I03aE0C8]=X6I>>dOoI@I-YD\er[8e'j8ng#b[B4ahZg9H37KI7<I/?>W$/^5A8[#ifpnGD%99%pXF)LI,8Lorl8=kpo/PsX'Z-WYMk/'7[KlQq%.:BY40VW-L?8e3Wjm=b@_[m%.XTUO2#,lLAJZCY-n90%/`]-nFPJWdTkG-aV>\RiZn8aPtt\`GI@\Uq?su^=2dtfn)4erY7o+>%:&1EIJ(AtCQhB$8Chqa!6h_nJ8b`DN8l95-G6G+KcB"9(b*j7q9cKSdXK<7CO<@?FL"J@m^6o=9W@oG>4t-krMG#FBcdOhddA[#.5&:ko15$K8tfgM<!"%JgZ9]Cc8kRbpF_7-dB*EhrK]SG!8f!5GJbN,8&4R&l^%D&pH%0./`[DMHBm8[$a;W1ei8bqaQQA063sc2kH/1.gb"H*ES/K8=u!q3^ESXsc;cI;S_KC:GAdE\IumR*i7i"u$M]84f>\mKr$(q7j"%kMp`98u-2s`d*7cgFL-Ve[bT0;+&-m]Lp$H+)f8b4`p^cBAL-HV>DrV:3gHM%,9[BQ\P6Q56->?"^``/lZ*9/ED7npMB.*Zg<cRa;ib+")V[o+YJP47;*V4F-!ddPF'Wu4N,Z/jdZ4skZ)rM?k_:PQ;BZhC5n#1O9/RGjNb<&0H]8;ND3c>q-KduiP7^M5ufhC4*N<RAAbU1ohV\!ebpTX\8k#+:iI!K!@D%E*-/[mOKp79heieYA*"mOiX_@\B^2\AgY9=1+e;QL=56e[*qBmdAcSHmR3ZoH/d9):8%\G)GS._tHo3`5;a(8.f!#d"3e1m7InJrrBB,m2+cC*U'+'DYur$pk%Mb8>`f(Q/a;M^2O-Ee[@NI</)CNj,=oQb)5i_Sem,qKu1]lGu:VrBu4R2eYC<fH98=qg(c)ba][?<aaY**3dc2IjkuVhL";m&^8k^#3MI/1/ZpC9,`<cIFD;WS7EZ?p!W(EWp`JG&SJUYQ@IS'l4@.sf:eaY^:ct]bR7UI"AiCibaN=V+Y=5BI4Z:2]dr%!j>1"rSDW#bW@$G55NIb,2*Phl>`jrDC':p-^>8rXA4C)]drKk89`]TT)`Mfh?^#*Vh.+>M>]<gYKqZ_:;g.+j^j42tu"j';o;6_3@Z7%*X!k=kRIK["PH2DICh@\1`;&6\GP?g-@Q+5e^=A$Li$NS=VBu)ola+<P8hsaEKJ_*tD>f!OeP1^kt>Bhg[.2_\Tn?ZWi8b]C*i7I>+n@RV5V`q`OFM>B%RNiBWeLhV=MDKia![9&<##6u/3$_SC;W'*39]$.WQ=!Do)AQa[;cW!YnUnS+Mb,O5QF>8`a\dH-g=GjT5MA'3*]3C'm7$O1`*+OC05e/o>FS!&HO[SL:jH,S=7[C?-53#@)<VmRYAs)]M^O@/-`VE7$._&b2!OCj7i;S=2F'h,h-)X:l1c6R%t_a[.s!_!C0]1_Vn/X7DnOml-Jrn)rr@\d&AC:+bZ\VPnETK9I_XBbC+XH!M!\eZYuO/J@n'U"pL=>Qnot2M&T3%WIb4QPnG`KDDZ1+%BJt0acf\V>>=tq/85m`VRRBsP=N1m\Oq1KA5/O&.6iJ7c,$B;6b.3L'?rLFEjat-E\WhBfk1stN)>b4f="OrTIr7INps[8%hgl``4rCu_<o6`aNo@)lg//0"[jkXD\thgYESt[o,/*GEJkMXik1UQnaTJOOj!:T*VkUoG#EdBLk.&WWADFFpQWdO46]kU'C@5c.Pah)c-gVH'Ii*D`_0Ys&]>Ji]A'_3U_]A@R(4D$o+^:*136j3K3'8*dg;h#.0_%*@hhJ_7LV,KkHZ*]#ip(l(%#G5Xi-`U9g`'7R>6>4Xi7GY>?;u/2#p'hZOo&:.3&nWh0)963Ssm'*6@G$jI"?q8BVLC]"&P_L-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ig!!-ii[!U5nkC5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Qqj!5Tg$Z~>endstream
+endobj
+% 'F2': class PDFType1Font
+4 0 obj
+% Font Helvetica-Bold
+<< /BaseFont /Helvetica-Bold
+ /Encoding /WinAnsiEncoding
+ /Name /F2
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER1': class PDFDictionary
+5 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 55
+ 626.125
+ 145.135
+ 637.375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER2': class LinkAnnotation
+6 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 564.9375
+ 117.5275
+ 576.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER3': class LinkAnnotation
+7 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 55
+ 501.8263
+ 0 ]
+ /Rect [ 70
+ 553.6875
+ 114.1825
+ 564.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER4': class LinkAnnotation
+8 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 586.8887
+ 0 ]
+ /Rect [ 70
+ 542.4375
+ 107.935
+ 553.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER5': class LinkAnnotation
+9 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 503.61
+ 0 ]
+ /Rect [ 85
+ 529.1875
+ 190.045
+ 540.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER6': class LinkAnnotation
+10 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 362.485
+ 0 ]
+ /Rect [ 85
+ 517.9375
+ 172.12
+ 529.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER7': class LinkAnnotation
+11 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 55
+ 286.1775
+ 0 ]
+ /Rect [ 100
+ 504.6875
+ 161.6875
+ 515.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER8': class LinkAnnotation
+12 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 701.615
+ 0 ]
+ /Rect [ 100
+ 493.4375
+ 178.3675
+ 504.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER9': class LinkAnnotation
+13 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 701.615
+ 0 ]
+ /Rect [ 100
+ 482.1875
+ 184.6225
+ 493.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER10': class LinkAnnotation
+14 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 637.615
+ 0 ]
+ /Rect [ 115
+ 468.9375
+ 221.725
+ 480.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER11': class LinkAnnotation
+15 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 271.615
+ 0 ]
+ /Rect [ 115
+ 457.6875
+ 195.46
+ 468.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER12': class LinkAnnotation
+16 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 137 0 R
+ /XYZ
+ 55
+ 185.115
+ 0 ]
+ /Rect [ 115
+ 446.4375
+ 206.7175
+ 457.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER13': class LinkAnnotation
+17 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 742.865
+ 0 ]
+ /Rect [ 115
+ 435.1875
+ 200.47
+ 446.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER14': class LinkAnnotation
+18 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 678.0475
+ 0 ]
+ /Rect [ 85
+ 421.9375
+ 180.0325
+ 433.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER15': class LinkAnnotation
+19 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 206.1725
+ 0 ]
+ /Rect [ 85
+ 410.6875
+ 160.0225
+ 421.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER16': class LinkAnnotation
+20 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 139 0 R
+ /XYZ
+ 55
+ 118.615
+ 0 ]
+ /Rect [ 100
+ 397.4375
+ 197.53
+ 408.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER17': class LinkAnnotation
+21 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 390.615
+ 0 ]
+ /Rect [ 100
+ 386.1875
+ 193.36
+ 397.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER18': class LinkAnnotation
+22 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 154 0 R
+ /XYZ
+ 55
+ 171.2975
+ 0 ]
+ /Rect [ 85
+ 372.9375
+ 194.2075
+ 384.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER19': class LinkAnnotation
+23 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 156 0 R
+ /XYZ
+ 55
+ 653.5475
+ 0 ]
+ /Rect [ 85
+ 361.6875
+ 157.5325
+ 372.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER20': class LinkAnnotation
+24 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 156 0 R
+ /XYZ
+ 55
+ 227.9225
+ 0 ]
+ /Rect [ 85
+ 350.4375
+ 196.285
+ 361.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER21': class LinkAnnotation
+25 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 156 0 R
+ /XYZ
+ 55
+ 130.0475
+ 0 ]
+ /Rect [ 85
+ 339.1875
+ 191.7025
+ 350.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER22': class LinkAnnotation
+26 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 710.865
+ 0 ]
+ /Rect [ 100
+ 325.9375
+ 147.94
+ 337.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER23': class LinkAnnotation
+27 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 592.365
+ 0 ]
+ /Rect [ 100
+ 314.6875
+ 161.695
+ 325.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER24': class LinkAnnotation
+28 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 485.115
+ 0 ]
+ /Rect [ 100
+ 303.4375
+ 144.61
+ 314.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER25': class LinkAnnotation
+29 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 312.115
+ 0 ]
+ /Rect [ 100
+ 292.1875
+ 143.3575
+ 303.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER26': class LinkAnnotation
+30 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 165 0 R
+ /XYZ
+ 55
+ 259.365
+ 0 ]
+ /Rect [ 100
+ 280.9375
+ 174.1975
+ 292.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER27': class LinkAnnotation
+31 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 267.6875
+ 197.1325
+ 278.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER28': class LinkAnnotation
+32 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 642.8262
+ 0 ]
+ /Rect [ 70
+ 256.4375
+ 159.6025
+ 267.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER29': class LinkAnnotation
+33 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 559.5475
+ 0 ]
+ /Rect [ 85
+ 243.1875
+ 147.5275
+ 254.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER30': class LinkAnnotation
+34 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 170 0 R
+ /XYZ
+ 55
+ 407.1725
+ 0 ]
+ /Rect [ 85
+ 231.9375
+ 160.45
+ 243.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER31': class LinkAnnotation
+35 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 171 0 R
+ /XYZ
+ 55
+ 620.5475
+ 0 ]
+ /Rect [ 85
+ 220.6875
+ 160.0375
+ 231.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER32': class LinkAnnotation
+36 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 171 0 R
+ /XYZ
+ 55
+ 297.6035
+ 0 ]
+ /Rect [ 85
+ 209.4375
+ 155.035
+ 220.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER33': class LinkAnnotation
+37 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 176 0 R
+ /XYZ
+ 55
+ 745.7975
+ 0 ]
+ /Rect [ 85
+ 198.1875
+ 147.1225
+ 209.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER34': class LinkAnnotation
+38 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 176 0 R
+ /XYZ
+ 55
+ 302.7638
+ 0 ]
+ /Rect [ 70
+ 184.9375
+ 174.1975
+ 196.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER35': class LinkAnnotation
+39 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 179 0 R
+ /XYZ
+ 55
+ 720.8887
+ 0 ]
+ /Rect [ 70
+ 173.6875
+ 155.8525
+ 184.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER36': class LinkAnnotation
+40 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 179 0 R
+ /XYZ
+ 55
+ 445.36
+ 0 ]
+ /Rect [ 85
+ 160.4375
+ 170.8675
+ 171.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER37': class LinkAnnotation
+41 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 179 0 R
+ /XYZ
+ 55
+ 369.0525
+ 0 ]
+ /Rect [ 100
+ 147.1875
+ 195.0475
+ 158.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER38': class LinkAnnotation
+42 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 722.115
+ 0 ]
+ /Rect [ 100
+ 135.9375
+ 171.685
+ 147.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER39': class LinkAnnotation
+43 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 680.615
+ 0 ]
+ /Rect [ 100
+ 124.6875
+ 205.0525
+ 135.9375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER40': class LinkAnnotation
+44 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 616.615
+ 0 ]
+ /Rect [ 100
+ 113.4375
+ 183.3775
+ 124.6875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER41': class LinkAnnotation
+45 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 509.365
+ 0 ]
+ /Rect [ 100
+ 102.1875
+ 201.7075
+ 113.4375 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER42': class LinkAnnotation
+46 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 303.2975
+ 0 ]
+ /Rect [ 85
+ 88.9375
+ 145.03
+ 100.1875 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page1': class PDFPage
+47 0 obj
+% Page dictionary
+<< /Annots [ 5 0 R
+ 6 0 R
+ 7 0 R
+ 8 0 R
+ 9 0 R
+ 10 0 R
+ 11 0 R
+ 12 0 R
+ 13 0 R
+ 14 0 R
+ 15 0 R
+ 16 0 R
+ 17 0 R
+ 18 0 R
+ 19 0 R
+ 20 0 R
+ 21 0 R
+ 22 0 R
+ 23 0 R
+ 24 0 R
+ 25 0 R
+ 26 0 R
+ 27 0 R
+ 28 0 R
+ 29 0 R
+ 30 0 R
+ 31 0 R
+ 32 0 R
+ 33 0 R
+ 34 0 R
+ 35 0 R
+ 36 0 R
+ 37 0 R
+ 38 0 R
+ 39 0 R
+ 40 0 R
+ 41 0 R
+ 42 0 R
+ 43 0 R
+ 44 0 R
+ 45 0 R
+ 46 0 R ]
+ /Contents 303 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ]
+ /XObject << /FormXob.c4c4c9f90f2c427799b277ddd57a9a5b 3 0 R >> >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER43': class LinkAnnotation
+48 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 249.49
+ 0 ]
+ /Rect [ 100
+ 730.6775
+ 152.95
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER44': class LinkAnnotation
+49 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 182 0 R
+ /XYZ
+ 55
+ 111.74
+ 0 ]
+ /Rect [ 100
+ 719.4275
+ 192.9625
+ 730.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER45': class LinkAnnotation
+50 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 684.365
+ 0 ]
+ /Rect [ 100
+ 708.1775
+ 173.785
+ 719.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER46': class LinkAnnotation
+51 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 588.365
+ 0 ]
+ /Rect [ 100
+ 696.9275
+ 182.545
+ 708.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER47': class LinkAnnotation
+52 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 474.2975
+ 0 ]
+ /Rect [ 85
+ 683.6775
+ 127.105
+ 694.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER48': class LinkAnnotation
+53 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 232.24
+ 0 ]
+ /Rect [ 100
+ 670.4275
+ 169.195
+ 681.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER49': class LinkAnnotation
+54 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 187 0 R
+ /XYZ
+ 55
+ 116.99
+ 0 ]
+ /Rect [ 100
+ 659.1775
+ 169.2025
+ 670.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER50': class LinkAnnotation
+55 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 669.115
+ 0 ]
+ /Rect [ 100
+ 647.9275
+ 136.69
+ 659.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER51': class LinkAnnotation
+56 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 616.365
+ 0 ]
+ /Rect [ 100
+ 636.6775
+ 157.1125
+ 647.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER52': class LinkAnnotation
+57 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 516.365
+ 0 ]
+ /Rect [ 100
+ 625.4275
+ 155.86
+ 636.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER53': class LinkAnnotation
+58 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 440.865
+ 0 ]
+ /Rect [ 100
+ 614.1775
+ 165.8575
+ 625.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER54': class LinkAnnotation
+59 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 376.865
+ 0 ]
+ /Rect [ 100
+ 602.9275
+ 159.6175
+ 614.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER55': class LinkAnnotation
+60 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 335.365
+ 0 ]
+ /Rect [ 100
+ 591.6775
+ 177.5275
+ 602.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER56': class LinkAnnotation
+61 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 259.2975
+ 0 ]
+ /Rect [ 85
+ 578.4275
+ 158.365
+ 589.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER57': class LinkAnnotation
+62 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 189 0 R
+ /XYZ
+ 55
+ 194.24
+ 0 ]
+ /Rect [ 100
+ 565.1775
+ 155.8675
+ 576.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER58': class LinkAnnotation
+63 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 699.615
+ 0 ]
+ /Rect [ 100
+ 553.9275
+ 185.035
+ 565.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER59': class LinkAnnotation
+64 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 646.865
+ 0 ]
+ /Rect [ 100
+ 542.6775
+ 152.5375
+ 553.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER60': class LinkAnnotation
+65 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 539.615
+ 0 ]
+ /Rect [ 100
+ 531.4275
+ 213.7825
+ 542.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER61': class LinkAnnotation
+66 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 398.365
+ 0 ]
+ /Rect [ 100
+ 520.1775
+ 215.86
+ 531.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER62': class LinkAnnotation
+67 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 280.7975
+ 0 ]
+ /Rect [ 85
+ 506.9275
+ 130.015
+ 518.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER63': class LinkAnnotation
+68 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 193 0 R
+ /XYZ
+ 55
+ 193.24
+ 0 ]
+ /Rect [ 100
+ 493.6775
+ 190.8625
+ 504.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER64': class LinkAnnotation
+69 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 710.865
+ 0 ]
+ /Rect [ 100
+ 482.4275
+ 192.115
+ 493.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER65': class LinkAnnotation
+70 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 475.115
+ 0 ]
+ /Rect [ 100
+ 471.1775
+ 193.375
+ 482.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER66': class LinkAnnotation
+71 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 223.115
+ 0 ]
+ /Rect [ 100
+ 459.9275
+ 186.2875
+ 471.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER67': class LinkAnnotation
+72 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 158.2975
+ 0 ]
+ /Rect [ 85
+ 446.6775
+ 169.6225
+ 457.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER68': class LinkAnnotation
+73 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 196 0 R
+ /XYZ
+ 55
+ 93.24
+ 0 ]
+ /Rect [ 100
+ 433.4275
+ 223.375
+ 444.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER69': class LinkAnnotation
+74 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 197 0 R
+ /XYZ
+ 55
+ 592.365
+ 0 ]
+ /Rect [ 100
+ 422.1775
+ 212.1475
+ 433.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER70': class LinkAnnotation
+75 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 197 0 R
+ /XYZ
+ 55
+ 335.5475
+ 0 ]
+ /Rect [ 85
+ 408.9275
+ 115.015
+ 420.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER71': class LinkAnnotation
+76 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 197 0 R
+ /XYZ
+ 55
+ 171.0138
+ 0 ]
+ /Rect [ 70
+ 395.6775
+ 166.2775
+ 406.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER72': class LinkAnnotation
+77 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 621.6388
+ 0 ]
+ /Rect [ 70
+ 384.4275
+ 172.945
+ 395.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER73': class LinkAnnotation
+78 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 527.11
+ 0 ]
+ /Rect [ 85
+ 371.1775
+ 140.4325
+ 382.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER74': class LinkAnnotation
+79 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 449.985
+ 0 ]
+ /Rect [ 85
+ 359.9275
+ 186.295
+ 371.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER75': class LinkAnnotation
+80 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 372.86
+ 0 ]
+ /Rect [ 85
+ 348.6775
+ 178.3525
+ 359.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER76': class LinkAnnotation
+81 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 202 0 R
+ /XYZ
+ 55
+ 306.985
+ 0 ]
+ /Rect [ 85
+ 337.4275
+ 212.56
+ 348.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER77': class LinkAnnotation
+82 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 591.1387
+ 0 ]
+ /Rect [ 70
+ 324.1775
+ 183.79
+ 335.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER78': class LinkAnnotation
+83 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 475.86
+ 0 ]
+ /Rect [ 85
+ 310.9275
+ 182.5375
+ 322.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER79': class LinkAnnotation
+84 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 300.985
+ 0 ]
+ /Rect [ 85
+ 299.6775
+ 144.6025
+ 310.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER80': class LinkAnnotation
+85 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 137.36
+ 0 ]
+ /Rect [ 85
+ 288.4275
+ 180.88
+ 299.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER81': class LinkAnnotation
+86 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 208 0 R
+ /XYZ
+ 55
+ 686.8887
+ 0 ]
+ /Rect [ 70
+ 275.1775
+ 148.375
+ 286.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER82': class LinkAnnotation
+87 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 208 0 R
+ /XYZ
+ 55
+ 459.9513
+ 0 ]
+ /Rect [ 70
+ 263.9275
+ 119.605
+ 275.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER83': class LinkAnnotation
+88 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 209 0 R
+ /XYZ
+ 55
+ 747.2637
+ 0 ]
+ /Rect [ 70
+ 252.6775
+ 200.065
+ 263.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page2': class PDFPage
+89 0 obj
+% Page dictionary
+<< /Annots [ 48 0 R
+ 49 0 R
+ 50 0 R
+ 51 0 R
+ 52 0 R
+ 53 0 R
+ 54 0 R
+ 55 0 R
+ 56 0 R
+ 57 0 R
+ 58 0 R
+ 59 0 R
+ 60 0 R
+ 61 0 R
+ 62 0 R
+ 63 0 R
+ 64 0 R
+ 65 0 R
+ 66 0 R
+ 67 0 R
+ 68 0 R
+ 69 0 R
+ 70 0 R
+ 71 0 R
+ 72 0 R
+ 73 0 R
+ 74 0 R
+ 75 0 R
+ 76 0 R
+ 77 0 R
+ 78 0 R
+ 79 0 R
+ 80 0 R
+ 81 0 R
+ 82 0 R
+ 83 0 R
+ 84 0 R
+ 85 0 R
+ 86 0 R
+ 87 0 R
+ 88 0 R ]
+ /Contents 304 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER84': class LinkAnnotation
+90 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 462.615
+ 0 ]
+ /Rect [ 125.8675
+ 663.865
+ 170.05
+ 675.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER85': class LinkAnnotation
+91 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 205 0 R
+ /XYZ
+ 55
+ 591.1387
+ 0 ]
+ /Rect [ 237.16
+ 579.115
+ 272.5975
+ 590.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER86': class LinkAnnotation
+92 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 436.115
+ 0 ]
+ /Rect [ 401.8075
+ 567.865
+ 445.99
+ 579.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER87': class PDFDictionary
+93 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.ietf.org/rfc/rfc2119.txt) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 189.625
+ 450.4275
+ 297.1675
+ 461.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER88': class PDFDictionary
+94 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 205.45
+ 437.1775
+ 369.6775
+ 448.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER89': class PDFDictionary
+95 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.965
+ 423.9275
+ 254.6725
+ 435.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER90': class PDFDictionary
+96 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/packages.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.2325
+ 410.6775
+ 363.4825
+ 421.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER91': class PDFDictionary
+97 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/Manifest.permission.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 172.9525
+ 397.4275
+ 413.8825
+ 408.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER92': class PDFDictionary
+98 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/os/Build.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.96
+ 384.1775
+ 358.885
+ 395.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER93': class PDFDictionary
+99 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://source.android.com/compatibility/2.3/versions.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 186.715
+ 370.9275
+ 373.45
+ 382.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER94': class PDFDictionary
+100 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/webkit/WebView.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 171.7
+ 357.6775
+ 400.96
+ 368.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER95': class PDFDictionary
+101 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.whatwg.org/specs/web-apps/current-work/multipage/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 95.005
+ 344.4275
+ 307.1575
+ 355.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER96': class PDFDictionary
+102 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://dev.w3.org/html5/spec/Overview.html#offline) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 159.955
+ 331.1775
+ 327.52
+ 342.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER97': class PDFDictionary
+103 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://dev.w3.org/html5/spec/Overview.html#video) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 131.2
+ 317.9275
+ 296.68
+ 329.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER98': class PDFDictionary
+104 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.w3.org/TR/geolocation-API/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 172.045
+ 304.6775
+ 300.8425
+ 315.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER99': class PDFDictionary
+105 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.w3.org/TR/webdatabase/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 178.3
+ 291.4275
+ 298.765
+ 302.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER100': class PDFDictionary
+106 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://www.w3.org/TR/IndexedDB/) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 170.7925
+ 278.1775
+ 283.75
+ 289.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER101': class PDFDictionary
+107 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/widget_design.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.5275
+ 251.6775
+ 374.23
+ 262.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER102': class PDFDictionary
+108 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/ui/notifiers/notifications.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 114.94
+ 238.4275
+ 346.2925
+ 249.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER103': class PDFDictionary
+109 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/android/reference/available-resources.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 148.705
+ 225.1775
+ 368.8
+ 236.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER104': class PDFDictionary
+110 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/ui_guidelines/icon_design.html#statusbarstructure) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 162.8875
+ 211.9275
+ 477.1975
+ 223.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER105': class PDFDictionary
+111 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/app/SearchManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.535
+ 198.6775
+ 371.7325
+ 209.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER106': class PDFDictionary
+112 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/widget/Toast.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 96.6025
+ 185.4275
+ 313.3675
+ 196.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER107': class PDFDictionary
+113 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/resources/articles/live-wallpapers.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 127.4425
+ 172.1775
+ 351.265
+ 183.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER108': class PDFDictionary
+114 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/index.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 245.845
+ 158.9275
+ 453.865
+ 170.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER109': class PDFDictionary
+115 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/fundamentals.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 164.1325
+ 145.6775
+ 364.645
+ 156.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER110': class PDFDictionary
+116 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/manifest/manifest-intro.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 117.8575
+ 132.4275
+ 349.2025
+ 143.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER111': class PDFDictionary
+117 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/developing/tools/monkey.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 138.7075
+ 119.1775
+ 355.06
+ 130.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER112': class PDFDictionary
+118 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/pm/PackageManager.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 179.965
+ 105.9275
+ 452.1775
+ 117.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER113': class PDFDictionary
+119 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/practices/screens_support.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 167.8825
+ 92.6775
+ 389.23
+ 103.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER114': class PDFDictionary
+120 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/util/DisplayMetrics.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.6125
+ 79.4275
+ 396.28
+ 90.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page3': class PDFPage
+121 0 obj
+% Page dictionary
+<< /Annots [ 90 0 R
+ 91 0 R
+ 92 0 R
+ 93 0 R
+ 94 0 R
+ 95 0 R
+ 96 0 R
+ 97 0 R
+ 98 0 R
+ 99 0 R
+ 100 0 R
+ 101 0 R
+ 102 0 R
+ 103 0 R
+ 104 0 R
+ 105 0 R
+ 106 0 R
+ 107 0 R
+ 108 0 R
+ 109 0 R
+ 110 0 R
+ 111 0 R
+ 112 0 R
+ 113 0 R
+ 114 0 R
+ 115 0 R
+ 116 0 R
+ 117 0 R
+ 118 0 R
+ 119 0 R
+ 120 0 R ]
+ /Contents 305 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER115': class PDFDictionary
+122 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/content/res/Configuration.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 184.9825
+ 730.6775
+ 443.02
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER116': class PDFDictionary
+123 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/SensorEvent.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 157.0525
+ 717.4275
+ 407.5825
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER117': class PDFDictionary
+124 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/bluetooth/package-summary.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 119.9575
+ 704.1775
+ 388.825
+ 715.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER118': class PDFDictionary
+125 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation\(int\)) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 152.0425
+ 690.9275
+ 474.6625
+ 702.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER119': class PDFDictionary
+126 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/reference/android/hardware/Camera.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 161.2075
+ 677.6775
+ 395.47
+ 688.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER120': class PDFDictionary
+127 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://developer.android.com/guide/topics/security/security.html) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 220.3975
+ 664.4275
+ 429.6475
+ 675.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER121': class PDFDictionary
+128 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (http://code.google.com/p/apps-for-android) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 129.955
+ 651.1775
+ 269.1925
+ 662.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER122': class LinkAnnotation
+129 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 422.865
+ 0 ]
+ /Rect [ 460.615
+ 435.865
+ 504.7975
+ 447.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER123': class LinkAnnotation
+130 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 409.615
+ 0 ]
+ /Rect [ 470.995
+ 253.24
+ 515.1775
+ 264.49 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F3': class PDFType1Font
+131 0 obj
+% Font Courier
+<< /BaseFont /Courier
+ /Encoding /WinAnsiEncoding
+ /Name /F3
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER124': class LinkAnnotation
+132 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 396.365
+ 0 ]
+ /Rect [ 336.2725
+ 200.49
+ 380.455
+ 211.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F4': class PDFType1Font
+133 0 obj
+% Font Times-Roman
+<< /BaseFont /Times-Roman
+ /Encoding /WinAnsiEncoding
+ /Name /F4
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER125': class LinkAnnotation
+134 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 383.115
+ 0 ]
+ /Rect [ 350.19
+ 124.49
+ 394.3725
+ 135.74 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page4': class PDFPage
+135 0 obj
+% Page dictionary
+<< /Annots [ 122 0 R
+ 123 0 R
+ 124 0 R
+ 125 0 R
+ 126 0 R
+ 127 0 R
+ 128 0 R
+ 129 0 R
+ 130 0 R
+ 132 0 R
+ 134 0 R ]
+ /Contents 306 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page5': class PDFPage
+136 0 obj
+% Page dictionary
+<< /Contents 307 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page6': class PDFPage
+137 0 obj
+% Page dictionary
+<< /Contents 308 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER126': class LinkAnnotation
+138 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 369.865
+ 0 ]
+ /Rect [ 381.61
+ 160.9275
+ 425.7925
+ 172.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page7': class PDFPage
+139 0 obj
+% Page dictionary
+<< /Annots [ 138 0 R ]
+ /Contents 309 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER127': class LinkAnnotation
+140 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 356.615
+ 0 ]
+ /Rect [ 307.5925
+ 532.9275
+ 351.775
+ 544.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER128': class LinkAnnotation
+141 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 343.365
+ 0 ]
+ /Rect [ 183.8125
+ 500.9275
+ 232.165
+ 512.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER129': class LinkAnnotation
+142 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 330.115
+ 0 ]
+ /Rect [ 122.125
+ 487.6775
+ 170.4775
+ 498.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER130': class LinkAnnotation
+143 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 316.865
+ 0 ]
+ /Rect [ 108.775
+ 474.4275
+ 157.1275
+ 485.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER131': class LinkAnnotation
+144 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 303.615
+ 0 ]
+ /Rect [ 343.435
+ 453.6775
+ 391.7875
+ 464.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'F5': class PDFType1Font
+145 0 obj
+% Font Helvetica-Oblique
+<< /BaseFont /Helvetica-Oblique
+ /Encoding /WinAnsiEncoding
+ /Name /F5
+ /Subtype /Type1
+ /Type /Font >>
+endobj
+% 'Annot.NUMBER132': class LinkAnnotation
+146 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 290.365
+ 0 ]
+ /Rect [ 110.4475
+ 442.4275
+ 158.8
+ 453.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER133': class LinkAnnotation
+147 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 356.615
+ 0 ]
+ /Rect [ 160.4575
+ 282.4275
+ 204.64
+ 293.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER134': class LinkAnnotation
+148 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 343.365
+ 0 ]
+ /Rect [ 183.8125
+ 250.4275
+ 232.165
+ 261.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER135': class LinkAnnotation
+149 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 330.115
+ 0 ]
+ /Rect [ 122.125
+ 237.1775
+ 170.4775
+ 248.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER136': class LinkAnnotation
+150 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 316.865
+ 0 ]
+ /Rect [ 108.775
+ 223.9275
+ 157.1275
+ 235.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER137': class LinkAnnotation
+151 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 303.615
+ 0 ]
+ /Rect [ 343.435
+ 203.1775
+ 391.7875
+ 214.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER138': class LinkAnnotation
+152 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 290.365
+ 0 ]
+ /Rect [ 110.4475
+ 191.9275
+ 158.8
+ 203.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER139': class LinkAnnotation
+153 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 436.115
+ 0 ]
+ /Rect [ 125.4475
+ 114.8025
+ 169.63
+ 126.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page8': class PDFPage
+154 0 obj
+% Page dictionary
+<< /Annots [ 140 0 R
+ 141 0 R
+ 142 0 R
+ 143 0 R
+ 144 0 R
+ 146 0 R
+ 147 0 R
+ 148 0 R
+ 149 0 R
+ 150 0 R
+ 151 0 R
+ 152 0 R
+ 153 0 R ]
+ /Contents 310 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER140': class LinkAnnotation
+155 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 277.115
+ 0 ]
+ /Rect [ 500.1475
+ 182.6775
+ 548.5
+ 193.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page9': class PDFPage
+156 0 obj
+% Page dictionary
+<< /Annots [ 155 0 R ]
+ /Contents 311 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER141': class LinkAnnotation
+157 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 263.865
+ 0 ]
+ /Rect [ 515.1475
+ 677.9275
+ 553.075
+ 689.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER142': class LinkAnnotation
+158 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 263.865
+ 0 ]
+ /Rect [ 55
+ 666.6775
+ 63.34
+ 677.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER143': class LinkAnnotation
+159 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 250.615
+ 0 ]
+ /Rect [ 313.045
+ 559.4275
+ 361.3975
+ 570.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER144': class LinkAnnotation
+160 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 237.365
+ 0 ]
+ /Rect [ 448.06
+ 527.4275
+ 496.4125
+ 538.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER145': class LinkAnnotation
+161 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 224.115
+ 0 ]
+ /Rect [ 124.615
+ 516.1775
+ 172.9675
+ 527.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER146': class LinkAnnotation
+162 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 210.865
+ 0 ]
+ /Rect [ 132.535
+ 452.1775
+ 180.8875
+ 463.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER147': class LinkAnnotation
+163 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 197.615
+ 0 ]
+ /Rect [ 217.9075
+ 279.1775
+ 266.26
+ 290.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER148': class LinkAnnotation
+164 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 184.365
+ 0 ]
+ /Rect [ 73.7575
+ 215.1775
+ 122.11
+ 226.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page10': class PDFPage
+165 0 obj
+% Page dictionary
+<< /Annots [ 157 0 R
+ 158 0 R
+ 159 0 R
+ 160 0 R
+ 161 0 R
+ 162 0 R
+ 163 0 R
+ 164 0 R ]
+ /Contents 312 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER149': class LinkAnnotation
+166 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 171.115
+ 0 ]
+ /Rect [ 499.5925
+ 695.865
+ 547.945
+ 707.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER150': class LinkAnnotation
+167 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 157.865
+ 0 ]
+ /Rect [ 257.9875
+ 675.115
+ 306.34
+ 686.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER151': class LinkAnnotation
+168 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 144.615
+ 0 ]
+ /Rect [ 373.0375
+ 675.115
+ 421.39
+ 686.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER152': class LinkAnnotation
+169 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 277.115
+ 0 ]
+ /Rect [ 493.5025
+ 675.115
+ 541.855
+ 686.365 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page11': class PDFPage
+170 0 obj
+% Page dictionary
+<< /Annots [ 166 0 R
+ 167 0 R
+ 168 0 R
+ 169 0 R ]
+ /Contents 313 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page12': class PDFPage
+171 0 obj
+% Page dictionary
+<< /Contents 314 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER153': class LinkAnnotation
+172 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 378.895
+ 323.8025
+ 427.2475
+ 335.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER154': class LinkAnnotation
+173 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 171.115
+ 0 ]
+ /Rect [ 207.1
+ 219.365
+ 255.4525
+ 230.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER155': class LinkAnnotation
+174 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 171.115
+ 0 ]
+ /Rect [ 239.6275
+ 183.615
+ 287.98
+ 194.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER156': class LinkAnnotation
+175 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 131.365
+ 0 ]
+ /Rect [ 98.3425
+ 147.865
+ 146.695
+ 159.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page13': class PDFPage
+176 0 obj
+% Page dictionary
+<< /Annots [ 172 0 R
+ 173 0 R
+ 174 0 R
+ 175 0 R ]
+ /Contents 315 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER157': class LinkAnnotation
+177 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 392.7925
+ 454.74
+ 441.145
+ 465.99 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER158': class LinkAnnotation
+178 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 104.865
+ 0 ]
+ /Rect [ 258.0025
+ 388.865
+ 306.355
+ 400.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page14': class PDFPage
+179 0 obj
+% Page dictionary
+<< /Annots [ 177 0 R
+ 178 0 R ]
+ /Contents 316 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER159': class LinkAnnotation
+180 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 91.615
+ 0 ]
+ /Rect [ 462.835
+ 689.1775
+ 511.1875
+ 700.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER160': class LinkAnnotation
+181 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 259.42
+ 120.3025
+ 307.7725
+ 131.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page15': class PDFPage
+182 0 obj
+% Page dictionary
+<< /Annots [ 180 0 R
+ 181 0 R ]
+ /Contents 317 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER161': class LinkAnnotation
+183 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 381.79
+ 717.4275
+ 430.1425
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER162': class LinkAnnotation
+184 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 742.865
+ 0 ]
+ /Rect [ 304.7875
+ 508.1775
+ 353.14
+ 519.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER163': class LinkAnnotation
+185 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 468.19
+ 385.8025
+ 516.5425
+ 397.0525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER164': class LinkAnnotation
+186 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 729.615
+ 0 ]
+ /Rect [ 382.21
+ 165.3025
+ 430.5625
+ 176.5525 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page16': class PDFPage
+187 0 obj
+% Page dictionary
+<< /Annots [ 183 0 R
+ 184 0 R
+ 185 0 R
+ 186 0 R ]
+ /Contents 318 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER165': class LinkAnnotation
+188 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 729.615
+ 0 ]
+ /Rect [ 382.21
+ 717.4275
+ 430.5625
+ 728.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page17': class PDFPage
+189 0 obj
+% Page dictionary
+<< /Annots [ 188 0 R ]
+ /Contents 319 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER166': class LinkAnnotation
+190 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 716.365
+ 0 ]
+ /Rect [ 297.6025
+ 602.6775
+ 345.955
+ 613.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER167': class LinkAnnotation
+191 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 68.335
+ 463.4275
+ 116.6875
+ 474.6775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER168': class LinkAnnotation
+192 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 69.925
+ 118.115
+ 0 ]
+ /Rect [ 320.2675
+ 418.1775
+ 368.62
+ 429.4275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page18': class PDFPage
+193 0 obj
+% Page dictionary
+<< /Annots [ 190 0 R
+ 191 0 R
+ 192 0 R ]
+ /Contents 320 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER169': class LinkAnnotation
+194 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 703.115
+ 0 ]
+ /Rect [ 293.17
+ 545.9275
+ 341.5225
+ 557.1775 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER170': class LinkAnnotation
+195 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 689.865
+ 0 ]
+ /Rect [ 425.56
+ 353.6775
+ 473.9125
+ 364.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page19': class PDFPage
+196 0 obj
+% Page dictionary
+<< /Annots [ 194 0 R
+ 195 0 R ]
+ /Contents 321 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page20': class PDFPage
+197 0 obj
+% Page dictionary
+<< /Contents 322 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER171': class LinkAnnotation
+198 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 164.2225
+ 558.99
+ 212.575
+ 570.24 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER172': class LinkAnnotation
+199 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 465.5875
+ 481.865
+ 513.94
+ 493.115 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER173': class LinkAnnotation
+200 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 345.55
+ 382.24
+ 393.9025
+ 393.49 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER174': class LinkAnnotation
+201 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 676.615
+ 0 ]
+ /Rect [ 57.085
+ 316.365
+ 105.4375
+ 327.615 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page21': class PDFPage
+202 0 obj
+% Page dictionary
+<< /Annots [ 198 0 R
+ 199 0 R
+ 200 0 R
+ 201 0 R ]
+ /Contents 323 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER175': class LinkAnnotation
+203 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 449.365
+ 0 ]
+ /Rect [ 323.41
+ 430.615
+ 367.5925
+ 441.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER176': class LinkAnnotation
+204 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 121 0 R
+ /XYZ
+ 66.25
+ 449.365
+ 0 ]
+ /Rect [ 315.115
+ 321.615
+ 359.2975
+ 332.865 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page22': class PDFPage
+205 0 obj
+% Page dictionary
+<< /Annots [ 203 0 R
+ 204 0 R ]
+ /Contents 324 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Annot.NUMBER177': class LinkAnnotation
+206 0 obj
+<< /Border [ 0
+ 0
+ 0 ]
+ /Contents ()
+ /Dest [ 135 0 R
+ /XYZ
+ 69.925
+ 663.365
+ 0 ]
+ /Rect [ 188.2975
+ 730.6775
+ 236.65
+ 741.9275 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Annot.NUMBER178': class PDFDictionary
+207 0 obj
+<< /A << /S /URI
+ /Type /Action
+ /URI (mailto:compatibility@android.com) >>
+ /Border [ 0
+ 0
+ 0 ]
+ /Rect [ 193.8325
+ 408.5525
+ 283.9675
+ 419.8025 ]
+ /Subtype /Link
+ /Type /Annot >>
+endobj
+% 'Page23': class PDFPage
+208 0 obj
+% Page dictionary
+<< /Annots [ 206 0 R
+ 207 0 R ]
+ /Contents 325 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'Page24': class PDFPage
+209 0 obj
+% Page dictionary
+<< /Contents 326 0 R
+ /MediaBox [ 0
+ 0
+ 612
+ 792 ]
+ /Parent 302 0 R
+ /Resources << /Font 1 0 R
+ /ProcSet [ /PDF
+ /Text
+ /ImageB
+ /ImageC
+ /ImageI ] >>
+ /Rotate 0
+ /Trans << >>
+ /Type /Page >>
+endobj
+% 'R210': class PDFCatalog
+210 0 obj
+% Document Root
+<< /Outlines 212 0 R
+ /PageMode /UseNone
+ /Pages 302 0 R
+ /Type /Catalog >>
+endobj
+% 'R211': class PDFInfo
+211 0 obj
+<< /Author ()
+ /CreationDate (D:20101215173620+08'00')
+ /Keywords ()
+ /Producer (pisa HTML to PDF <http://www.htmltopdf.org>)
+ /Subject ()
+ /Title (Android 2.3 Compatibility Definition) >>
+endobj
+% 'R212': class PDFOutlines
+212 0 obj
+<< /Count 17
+ /First 213 0 R
+ /Last 213 0 R
+ /Type /Outlines >>
+endobj
+% 'Outline.0': class OutlineEntryObject
+213 0 obj
+<< /Count -14
+ /Dest [ 47 0 R
+ /Fit ]
+ /First 214 0 R
+ /Last 296 0 R
+ /Parent 212 0 R
+ /Title (Android 2.3 Compatibility Definition) >>
+endobj
+% 'Outline.2.0': class OutlineEntryObject
+214 0 obj
+<< /Dest [ 47 0 R
+ /Fit ]
+ /Next 215 0 R
+ /Parent 213 0 R
+ /Title (Table of Contents) >>
+endobj
+% 'Outline.2.1': class OutlineEntryObject
+215 0 obj
+<< /Dest [ 121 0 R
+ /Fit ]
+ /Next 216 0 R
+ /Parent 213 0 R
+ /Prev 214 0 R
+ /Title (1. Introduction) >>
+endobj
+% 'Outline.2.2': class OutlineEntryObject
+216 0 obj
+<< /Dest [ 121 0 R
+ /Fit ]
+ /Next 217 0 R
+ /Parent 213 0 R
+ /Prev 215 0 R
+ /Title (2. Resources) >>
+endobj
+% 'Outline.2.3': class OutlineEntryObject
+217 0 obj
+<< /Count -8
+ /Dest [ 135 0 R
+ /Fit ]
+ /First 218 0 R
+ /Last 234 0 R
+ /Next 240 0 R
+ /Parent 213 0 R
+ /Prev 216 0 R
+ /Title (3. Software) >>
+endobj
+% 'Outline.3.0': class OutlineEntryObject
+218 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 219 0 R
+ /Parent 217 0 R
+ /Title (3.1. Managed API Compatibility) >>
+endobj
+% 'Outline.3.1': class OutlineEntryObject
+219 0 obj
+<< /Count -7
+ /Dest [ 135 0 R
+ /Fit ]
+ /First 220 0 R
+ /Last 226 0 R
+ /Next 227 0 R
+ /Parent 217 0 R
+ /Prev 218 0 R
+ /Title (3.2. Soft API Compatibility) >>
+endobj
+% 'Outline.4.0': class OutlineEntryObject
+220 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 221 0 R
+ /Parent 219 0 R
+ /Title (3.2.1. Permissions) >>
+endobj
+% 'Outline.4.1': class OutlineEntryObject
+221 0 obj
+<< /Dest [ 135 0 R
+ /Fit ]
+ /Next 222 0 R
+ /Parent 219 0 R
+ /Prev 220 0 R
+ /Title (3.2.2. Build Parameters) >>
+endobj
+% 'Outline.4.2': class OutlineEntryObject
+222 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 223 0 R
+ /Parent 219 0 R
+ /Prev 221 0 R
+ /Title (3.2.3. Intent Compatibility) >>
+endobj
+% 'Outline.4.3': class OutlineEntryObject
+223 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 224 0 R
+ /Parent 219 0 R
+ /Prev 222 0 R
+ /Title (3.2.3.1. Core Application Intents) >>
+endobj
+% 'Outline.4.4': class OutlineEntryObject
+224 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 225 0 R
+ /Parent 219 0 R
+ /Prev 223 0 R
+ /Title (3.2.3.2. Intent Overrides) >>
+endobj
+% 'Outline.4.5': class OutlineEntryObject
+225 0 obj
+<< /Dest [ 137 0 R
+ /Fit ]
+ /Next 226 0 R
+ /Parent 219 0 R
+ /Prev 224 0 R
+ /Title (3.2.3.3. Intent Namespaces) >>
+endobj
+% 'Outline.4.6': class OutlineEntryObject
+226 0 obj
+<< /Dest [ 139 0 R
+ /Fit ]
+ /Parent 219 0 R
+ /Prev 225 0 R
+ /Title (3.2.3.4. Broadcast Intents) >>
+endobj
+% 'Outline.3.2': class OutlineEntryObject
+227 0 obj
+<< /Dest [ 139 0 R
+ /Fit ]
+ /Next 228 0 R
+ /Parent 217 0 R
+ /Prev 219 0 R
+ /Title (3.3. Native API Compatibility) >>
+endobj
+% 'Outline.3.3': class OutlineEntryObject
+228 0 obj
+<< /Count -2
+ /Dest [ 139 0 R
+ /Fit ]
+ /First 229 0 R
+ /Last 230 0 R
+ /Next 231 0 R
+ /Parent 217 0 R
+ /Prev 227 0 R
+ /Title (3.4. Web Compatibility) >>
+endobj
+% 'Outline.5.0': class OutlineEntryObject
+229 0 obj
+<< /Dest [ 139 0 R
+ /Fit ]
+ /Next 230 0 R
+ /Parent 228 0 R
+ /Title (3.4.1. WebView Compatibility) >>
+endobj
+% 'Outline.5.1': class OutlineEntryObject
+230 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Parent 228 0 R
+ /Prev 229 0 R
+ /Title (3.4.2. Browser Compatibility) >>
+endobj
+% 'Outline.3.4': class OutlineEntryObject
+231 0 obj
+<< /Dest [ 154 0 R
+ /Fit ]
+ /Next 232 0 R
+ /Parent 217 0 R
+ /Prev 228 0 R
+ /Title (3.5. API Behavioral Compatibility) >>
+endobj
+% 'Outline.3.5': class OutlineEntryObject
+232 0 obj
+<< /Dest [ 156 0 R
+ /Fit ]
+ /Next 233 0 R
+ /Parent 217 0 R
+ /Prev 231 0 R
+ /Title (3.6. API Namespaces) >>
+endobj
+% 'Outline.3.6': class OutlineEntryObject
+233 0 obj
+<< /Dest [ 156 0 R
+ /Fit ]
+ /Next 234 0 R
+ /Parent 217 0 R
+ /Prev 232 0 R
+ /Title (3.7. Virtual Machine Compatibility) >>
+endobj
+% 'Outline.3.7': class OutlineEntryObject
+234 0 obj
+<< /Count -5
+ /Dest [ 156 0 R
+ /Fit ]
+ /First 235 0 R
+ /Last 239 0 R
+ /Parent 217 0 R
+ /Prev 233 0 R
+ /Title (3.8. User Interface Compatibility) >>
+endobj
+% 'Outline.6.0': class OutlineEntryObject
+235 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 236 0 R
+ /Parent 234 0 R
+ /Title (3.8.1. Widgets) >>
+endobj
+% 'Outline.6.1': class OutlineEntryObject
+236 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 237 0 R
+ /Parent 234 0 R
+ /Prev 235 0 R
+ /Title (3.8.2. Notifications) >>
+endobj
+% 'Outline.6.2': class OutlineEntryObject
+237 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 238 0 R
+ /Parent 234 0 R
+ /Prev 236 0 R
+ /Title (3.8.3. Search) >>
+endobj
+% 'Outline.6.3': class OutlineEntryObject
+238 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Next 239 0 R
+ /Parent 234 0 R
+ /Prev 237 0 R
+ /Title (3.8.4. Toasts) >>
+endobj
+% 'Outline.6.4': class OutlineEntryObject
+239 0 obj
+<< /Dest [ 165 0 R
+ /Fit ]
+ /Parent 234 0 R
+ /Prev 238 0 R
+ /Title (3.8.5. Live Wallpapers) >>
+endobj
+% 'Outline.2.4': class OutlineEntryObject
+240 0 obj
+<< /Dest [ 170 0 R
+ /Fit ]
+ /Next 241 0 R
+ /Parent 213 0 R
+ /Prev 217 0 R
+ /Title (4. Application Packaging Compatibility) >>
+endobj
+% 'Outline.2.5': class OutlineEntryObject
+241 0 obj
+<< /Count -5
+ /Dest [ 170 0 R
+ /Fit ]
+ /First 242 0 R
+ /Last 246 0 R
+ /Next 247 0 R
+ /Parent 213 0 R
+ /Prev 240 0 R
+ /Title (5. Multimedia Compatibility) >>
+endobj
+% 'Outline.7.0': class OutlineEntryObject
+242 0 obj
+<< /Dest [ 170 0 R
+ /Fit ]
+ /Next 243 0 R
+ /Parent 241 0 R
+ /Title (5.1. Media Codecs) >>
+endobj
+% 'Outline.7.1': class OutlineEntryObject
+243 0 obj
+<< /Dest [ 170 0 R
+ /Fit ]
+ /Next 244 0 R
+ /Parent 241 0 R
+ /Prev 242 0 R
+ /Title (5.1.1. Media Decoders) >>
+endobj
+% 'Outline.7.2': class OutlineEntryObject
+244 0 obj
+<< /Dest [ 171 0 R
+ /Fit ]
+ /Next 245 0 R
+ /Parent 241 0 R
+ /Prev 243 0 R
+ /Title (5.1.2. Media Encoders) >>
+endobj
+% 'Outline.7.3': class OutlineEntryObject
+245 0 obj
+<< /Dest [ 171 0 R
+ /Fit ]
+ /Next 246 0 R
+ /Parent 241 0 R
+ /Prev 244 0 R
+ /Title (5.2. Audio Recording) >>
+endobj
+% 'Outline.7.4': class OutlineEntryObject
+246 0 obj
+<< /Dest [ 176 0 R
+ /Fit ]
+ /Parent 241 0 R
+ /Prev 245 0 R
+ /Title (5.3. Audio Latency) >>
+endobj
+% 'Outline.2.6': class OutlineEntryObject
+247 0 obj
+<< /Dest [ 176 0 R
+ /Fit ]
+ /Next 248 0 R
+ /Parent 213 0 R
+ /Prev 241 0 R
+ /Title (6. Developer Tool Compatibility) >>
+endobj
+% 'Outline.2.7': class OutlineEntryObject
+248 0 obj
+<< /Count -7
+ /Dest [ 179 0 R
+ /Fit ]
+ /First 249 0 R
+ /Last 283 0 R
+ /Next 284 0 R
+ /Parent 213 0 R
+ /Prev 247 0 R
+ /Title (7. Hardware Compatibility) >>
+endobj
+% 'Outline.8.0': class OutlineEntryObject
+249 0 obj
+<< /Count -5
+ /Dest [ 179 0 R
+ /Fit ]
+ /First 250 0 R
+ /Last 254 0 R
+ /Next 255 0 R
+ /Parent 248 0 R
+ /Title (7.1. Display and Graphics) >>
+endobj
+% 'Outline.9.0': class OutlineEntryObject
+250 0 obj
+<< /Dest [ 179 0 R
+ /Fit ]
+ /Next 251 0 R
+ /Parent 249 0 R
+ /Title (7.1.1. Screen Configurations) >>
+endobj
+% 'Outline.9.1': class OutlineEntryObject
+251 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 252 0 R
+ /Parent 249 0 R
+ /Prev 250 0 R
+ /Title (7.1.2. Display Metrics) >>
+endobj
+% 'Outline.9.2': class OutlineEntryObject
+252 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 253 0 R
+ /Parent 249 0 R
+ /Prev 251 0 R
+ /Title (7.1.3. Declared Screen Support) >>
+endobj
+% 'Outline.9.3': class OutlineEntryObject
+253 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 254 0 R
+ /Parent 249 0 R
+ /Prev 252 0 R
+ /Title (7.1.4. Screen Orientation) >>
+endobj
+% 'Outline.9.4': class OutlineEntryObject
+254 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Parent 249 0 R
+ /Prev 253 0 R
+ /Title (7.1.5. 3D Graphics Acceleration) >>
+endobj
+% 'Outline.8.1': class OutlineEntryObject
+255 0 obj
+<< /Count -4
+ /Dest [ 182 0 R
+ /Fit ]
+ /First 256 0 R
+ /Last 259 0 R
+ /Next 260 0 R
+ /Parent 248 0 R
+ /Prev 249 0 R
+ /Title (7.2. Input Devices) >>
+endobj
+% 'Outline.10.0': class OutlineEntryObject
+256 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 257 0 R
+ /Parent 255 0 R
+ /Title (7.2.1. Keyboard) >>
+endobj
+% 'Outline.10.1': class OutlineEntryObject
+257 0 obj
+<< /Dest [ 182 0 R
+ /Fit ]
+ /Next 258 0 R
+ /Parent 255 0 R
+ /Prev 256 0 R
+ /Title (7.2.2. Non-touch Navigation) >>
+endobj
+% 'Outline.10.2': class OutlineEntryObject
+258 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Next 259 0 R
+ /Parent 255 0 R
+ /Prev 257 0 R
+ /Title (7.2.3. Navigation keys) >>
+endobj
+% 'Outline.10.3': class OutlineEntryObject
+259 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Parent 255 0 R
+ /Prev 258 0 R
+ /Title (7.2.4. Touchscreen input) >>
+endobj
+% 'Outline.8.2': class OutlineEntryObject
+260 0 obj
+<< /Count -8
+ /Dest [ 187 0 R
+ /Fit ]
+ /First 261 0 R
+ /Last 268 0 R
+ /Next 269 0 R
+ /Parent 248 0 R
+ /Prev 255 0 R
+ /Title (7.3. Sensors) >>
+endobj
+% 'Outline.11.0': class OutlineEntryObject
+261 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Next 262 0 R
+ /Parent 260 0 R
+ /Title (7.3.1. Accelerometer) >>
+endobj
+% 'Outline.11.1': class OutlineEntryObject
+262 0 obj
+<< /Dest [ 187 0 R
+ /Fit ]
+ /Next 263 0 R
+ /Parent 260 0 R
+ /Prev 261 0 R
+ /Title (7.3.2. Magnetometer) >>
+endobj
+% 'Outline.11.2': class OutlineEntryObject
+263 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 264 0 R
+ /Parent 260 0 R
+ /Prev 262 0 R
+ /Title (7.3.3. GPS) >>
+endobj
+% 'Outline.11.3': class OutlineEntryObject
+264 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 265 0 R
+ /Parent 260 0 R
+ /Prev 263 0 R
+ /Title (7.3.4. Gyroscope) >>
+endobj
+% 'Outline.11.4': class OutlineEntryObject
+265 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 266 0 R
+ /Parent 260 0 R
+ /Prev 264 0 R
+ /Title (7.3.5. Barometer) >>
+endobj
+% 'Outline.11.5': class OutlineEntryObject
+266 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 267 0 R
+ /Parent 260 0 R
+ /Prev 265 0 R
+ /Title (7.3.7. Thermometer) >>
+endobj
+% 'Outline.11.6': class OutlineEntryObject
+267 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 268 0 R
+ /Parent 260 0 R
+ /Prev 266 0 R
+ /Title (7.3.7. Photometer) >>
+endobj
+% 'Outline.11.7': class OutlineEntryObject
+268 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Parent 260 0 R
+ /Prev 267 0 R
+ /Title (7.3.8. Proximity Sensor) >>
+endobj
+% 'Outline.8.3': class OutlineEntryObject
+269 0 obj
+<< /Count -5
+ /Dest [ 189 0 R
+ /Fit ]
+ /First 270 0 R
+ /Last 274 0 R
+ /Next 275 0 R
+ /Parent 248 0 R
+ /Prev 260 0 R
+ /Title (7.4. Data Connectivity) >>
+endobj
+% 'Outline.12.0': class OutlineEntryObject
+270 0 obj
+<< /Dest [ 189 0 R
+ /Fit ]
+ /Next 271 0 R
+ /Parent 269 0 R
+ /Title (7.4.1. Telephony) >>
+endobj
+% 'Outline.12.1': class OutlineEntryObject
+271 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 272 0 R
+ /Parent 269 0 R
+ /Prev 270 0 R
+ /Title (7.4.2. IEEE 802.11 \(WiFi\)) >>
+endobj
+% 'Outline.12.2': class OutlineEntryObject
+272 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 273 0 R
+ /Parent 269 0 R
+ /Prev 271 0 R
+ /Title (7.4.3. Bluetooth) >>
+endobj
+% 'Outline.12.3': class OutlineEntryObject
+273 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 274 0 R
+ /Parent 269 0 R
+ /Prev 272 0 R
+ /Title (7.4.4. Near-Field Communications) >>
+endobj
+% 'Outline.12.4': class OutlineEntryObject
+274 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Parent 269 0 R
+ /Prev 273 0 R
+ /Title (7.4.5. Minimum Network Capability) >>
+endobj
+% 'Outline.8.4': class OutlineEntryObject
+275 0 obj
+<< /Count -4
+ /Dest [ 193 0 R
+ /Fit ]
+ /First 276 0 R
+ /Last 279 0 R
+ /Next 280 0 R
+ /Parent 248 0 R
+ /Prev 269 0 R
+ /Title (7.5. Cameras) >>
+endobj
+% 'Outline.13.0': class OutlineEntryObject
+276 0 obj
+<< /Dest [ 193 0 R
+ /Fit ]
+ /Next 277 0 R
+ /Parent 275 0 R
+ /Title (7.5.1. Rear-Facing Camera) >>
+endobj
+% 'Outline.13.1': class OutlineEntryObject
+277 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Next 278 0 R
+ /Parent 275 0 R
+ /Prev 276 0 R
+ /Title (7.5.2. Front-Facing Camera) >>
+endobj
+% 'Outline.13.2': class OutlineEntryObject
+278 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Next 279 0 R
+ /Parent 275 0 R
+ /Prev 277 0 R
+ /Title (7.5.3. Camera API Behavior) >>
+endobj
+% 'Outline.13.3': class OutlineEntryObject
+279 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Parent 275 0 R
+ /Prev 278 0 R
+ /Title (7.5.4. Camera Orientation) >>
+endobj
+% 'Outline.8.5': class OutlineEntryObject
+280 0 obj
+<< /Count -2
+ /Dest [ 196 0 R
+ /Fit ]
+ /First 281 0 R
+ /Last 282 0 R
+ /Next 283 0 R
+ /Parent 248 0 R
+ /Prev 275 0 R
+ /Title (7.6. Memory and Storage) >>
+endobj
+% 'Outline.14.0': class OutlineEntryObject
+281 0 obj
+<< /Dest [ 196 0 R
+ /Fit ]
+ /Next 282 0 R
+ /Parent 280 0 R
+ /Title (7.6.1. Minimum Memory and Storage) >>
+endobj
+% 'Outline.14.1': class OutlineEntryObject
+282 0 obj
+<< /Dest [ 197 0 R
+ /Fit ]
+ /Parent 280 0 R
+ /Prev 281 0 R
+ /Title (7.6.2. Application Shared Storage) >>
+endobj
+% 'Outline.8.6': class OutlineEntryObject
+283 0 obj
+<< /Dest [ 197 0 R
+ /Fit ]
+ /Parent 248 0 R
+ /Prev 280 0 R
+ /Title (7.7. USB) >>
+endobj
+% 'Outline.2.8': class OutlineEntryObject
+284 0 obj
+<< /Dest [ 197 0 R
+ /Fit ]
+ /Next 285 0 R
+ /Parent 213 0 R
+ /Prev 248 0 R
+ /Title (8. Performance Compatibility) >>
+endobj
+% 'Outline.2.9': class OutlineEntryObject
+285 0 obj
+<< /Count -4
+ /Dest [ 202 0 R
+ /Fit ]
+ /First 286 0 R
+ /Last 289 0 R
+ /Next 290 0 R
+ /Parent 213 0 R
+ /Prev 284 0 R
+ /Title (9. Security Model Compatibility) >>
+endobj
+% 'Outline.15.0': class OutlineEntryObject
+286 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Next 287 0 R
+ /Parent 285 0 R
+ /Title (9.1. Permissions) >>
+endobj
+% 'Outline.15.1': class OutlineEntryObject
+287 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Next 288 0 R
+ /Parent 285 0 R
+ /Prev 286 0 R
+ /Title (9.2. UID and Process Isolation) >>
+endobj
+% 'Outline.15.2': class OutlineEntryObject
+288 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Next 289 0 R
+ /Parent 285 0 R
+ /Prev 287 0 R
+ /Title (9.3. Filesystem Permissions) >>
+endobj
+% 'Outline.15.3': class OutlineEntryObject
+289 0 obj
+<< /Dest [ 202 0 R
+ /Fit ]
+ /Parent 285 0 R
+ /Prev 288 0 R
+ /Title (9.4. Alternate Execution Environments) >>
+endobj
+% 'Outline.2.10': class OutlineEntryObject
+290 0 obj
+<< /Count -3
+ /Dest [ 205 0 R
+ /Fit ]
+ /First 291 0 R
+ /Last 293 0 R
+ /Next 294 0 R
+ /Parent 213 0 R
+ /Prev 285 0 R
+ /Title (10. Software Compatibility Testing) >>
+endobj
+% 'Outline.16.0': class OutlineEntryObject
+291 0 obj
+<< /Dest [ 205 0 R
+ /Fit ]
+ /Next 292 0 R
+ /Parent 290 0 R
+ /Title (10.1. Compatibility Test Suite) >>
+endobj
+% 'Outline.16.1': class OutlineEntryObject
+292 0 obj
+<< /Dest [ 205 0 R
+ /Fit ]
+ /Next 293 0 R
+ /Parent 290 0 R
+ /Prev 291 0 R
+ /Title (10.2. CTS Verifier) >>
+endobj
+% 'Outline.16.2': class OutlineEntryObject
+293 0 obj
+<< /Dest [ 205 0 R
+ /Fit ]
+ /Parent 290 0 R
+ /Prev 292 0 R
+ /Title (10.3. Reference Applications) >>
+endobj
+% 'Outline.2.11': class OutlineEntryObject
+294 0 obj
+<< /Dest [ 208 0 R
+ /Fit ]
+ /Next 295 0 R
+ /Parent 213 0 R
+ /Prev 290 0 R
+ /Title (11. Updatable Software) >>
+endobj
+% 'Outline.2.12': class OutlineEntryObject
+295 0 obj
+<< /Dest [ 208 0 R
+ /Fit ]
+ /Next 296 0 R
+ /Parent 213 0 R
+ /Prev 294 0 R
+ /Title (12. Contact Us) >>
+endobj
+% 'Outline.2.13': class OutlineEntryObject
+296 0 obj
+<< /Count -5
+ /Dest [ 209 0 R
+ /Fit ]
+ /First 297 0 R
+ /Last 301 0 R
+ /Parent 213 0 R
+ /Prev 295 0 R
+ /Title (Appendix A - Bluetooth Test Procedure) >>
+endobj
+% 'Outline.17.0': class OutlineEntryObject
+297 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 298 0 R
+ /Parent 296 0 R
+ /Title (Setup and Installation) >>
+endobj
+% 'Outline.17.1': class OutlineEntryObject
+298 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 299 0 R
+ /Parent 296 0 R
+ /Prev 297 0 R
+ /Title (Test Bluetooth Control by Apps) >>
+endobj
+% 'Outline.17.2': class OutlineEntryObject
+299 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 300 0 R
+ /Parent 296 0 R
+ /Prev 298 0 R
+ /Title (Test Pairing and Communication) >>
+endobj
+% 'Outline.17.3': class OutlineEntryObject
+300 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Next 301 0 R
+ /Parent 296 0 R
+ /Prev 299 0 R
+ /Title (Test Pairing and Communication in the Reverse Direction) >>
+endobj
+% 'Outline.17.4': class OutlineEntryObject
+301 0 obj
+<< /Dest [ 209 0 R
+ /Fit ]
+ /Parent 296 0 R
+ /Prev 300 0 R
+ /Title (Test Re-Launches) >>
+endobj
+% 'R302': class PDFPages
+302 0 obj
+% page tree
+<< /Count 24
+ /Kids [ 47 0 R
+ 89 0 R
+ 121 0 R
+ 135 0 R
+ 136 0 R
+ 137 0 R
+ 139 0 R
+ 154 0 R
+ 156 0 R
+ 165 0 R
+ 170 0 R
+ 171 0 R
+ 176 0 R
+ 179 0 R
+ 182 0 R
+ 187 0 R
+ 189 0 R
+ 193 0 R
+ 196 0 R
+ 197 0 R
+ 202 0 R
+ 205 0 R
+ 208 0 R
+ 209 0 R ]
+ /Type /Pages >>
+endobj
+% 'R303': class PDFStream
+303 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1782 >>
+stream
+Gatm=9lo&I&A<G1rrL0KdieGHa/sNTUm[&[-WZEPH@\XY7SAjN7+mcRT*6[c,V,!2m#acT+gD/nhqPUJL`umBgAGPUK[+5oofJ$Z6aJeI!Xgj^Lu-EP:VJbp\fEC,@LU9iCjPh)H:<&PE(i6&&j;bV^g$&PU)58?7'e26'Z4F*^RHstdS3<%O'SDckc\[n0:Mjjbl50KIc"FY*\Jd3;bY[1otZp5O^#2>`j]"X'?OFifC(3$r4BPZR=J'o:W],<K#M_uhSO3&k;$);P.0YLC=[@J6]S!i-b.6-9NrV5;pY$;^SuSB]R86ME5:Rd^G<dUKYJ3/&fk'pjZ)C?EIct*r!^t=oZt\8<[NUkE:g#2Y#K7U9k!</kX*TiBkgS3,6/0RbK(qiSQL%fgMpTWT:V9d'k&7!Gg-ktn3Sc%2[XX_F;"@64]qET>5b[;EEAobR&#NM8q';!X(kLFoV'J_3\(Qe$s4aTf@o*I*&im>ceI..Ha7OJr_RJ(0\gNbmcX0KQV8[eaTT&2'+q)@#FAj7n[S6339$[=K:',Qm(,D[\):pW#E6i0QhB&O;[EaUW@+EG(]bA;i,f?;"<:rlk>h]HEDmdnZdoggJ0q@=CVo_+4d+cGKKV#T'?nKcWeI!Q?qG49I$<qRU'LDP:km@6]rj7Oe*F8Y*2B!<?9]j=6b!4$+<dt.dZ#h((FI!T[_/)tPWHoJ)I)WnR_(gMF>$Xn(-4ruf,siM1`f!7#1:J-18Fu)R7.-"'g8Em'"-uf7<R"Q3b9<+(jk6c\m2-A<.M76C`!(eGB!d[Y-hQ(oc!Th6"K+s38^)I8(Yn`V674s1uV/$JJLBj3,h"d\;27n0\ZaqK#.qKp:&%N&#NXV_+$hALe%CHPSD0f(\+GjJO3fX+2utp7rdUVJIW/Tr(U`[3a8]nP:<DN>D,,CA:$-th.pe#4sb['k`GpJ5aq@<9hM:h'#6A/WB=,FqY1,i=[N=P6Wc-@:^.9LIEPPr64'$>V<jC6'S:T6T\\q3C+.$lS%a;o(@m+]b@`c*!]gK+,(McVFW6N/s&]Vp$kSZ,7R'!ePcQ%k"#Q+c%k-UL!Te`4j.MDXp=(tVf/;R'@%OcBO;OWS/.'H,[q?rGH/UDn&iU,:Y4'lRWN7S@!bg(%qoVird8siD%8:fAZ9)"MVbECaoTpe_dkj.Afq(n]kd\OA7*$,l9`&*4o[2[g`^EFB\`\:4e<>4W2Ca9$L5,=s$-7W*CSBtcE+).%?qW4oWptnBdh%]roMkc_S8);/[@(sVmc8W%GL4KEG>eT0gLh8NaiQJ.Q@*e^j-qNUQ!,3phkoWb8ap&+:]dS>8aYp?-ku>f9KK,%)1^@^>G5htrMLF.>kk3R"SHe6e7P\$URn%#1hFMrTV'HQ:>@@j#GhPA((jY>>aON`.2im56GPLTOFXBRU;-9DBA%*![lEM2)bh_>GX)*mB4*F-+*%R%BCNA%0nA4qS(q!,$bYBZ^ru9<HoM&"JrVi!,%)+?Fj,L1hT9S)H4ugiQUu*Dm2,V*(DV`HLh-13^&Z=RT??<akiV\D/Oc%=%SgLZn9CaNEKB_dST@'P$aX.Sl3C3uNo"!J\hf*Y5NuDkI\P7f/@W5<_H4#I*=-ec0gQfcKkf3:B+T0H"%>6\lU$9jIUAr[M-D.7afO'i48YS<`Pt[I(icTH3u2)dg)_M)hh&J!apQ4IHoL03B!nXT4_6)9C]%]Pm,upK+fdDNlH1dRlpPJh<bQiuEg!C.%mEbUrEDS_Mkja%S?gku:85tKD8u[<d-8YJM37pn~>endstream
+endobj
+% 'R304': class PDFStream
+304 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1512 >>
+stream
+Gatm<>uTK=&:J2Gs0.ROSO'Y/b9)d1"2in%V+nIJl&0NadB.8^Z301Fhj&c2VSQ::6XUaB2tHC.ZY)32!rSbZhn0(OR_bm8$C&Bn#&$OoR/I,Ng&Bj3p-kUt70nj7=J/IYSAG;T4sP'_.2-[8^PAFR2]'FYM$2$pTTnBhq"aX'QjA%Md/KD:pqT)1lp$m9e_^;5IJnKkkNg<HM,NX6.$&:q45Jep+;>@kKEVYd;F2:cZu]'ZFNBRjB`7-c3I4/rF#N#N@smaeQR3tQ3_(Et&IG(JAXKdK8aG##Zji%YL^p;N[],8n,F$"$Edb&G1N*rA.>09=hin__d+(FW=8;nMZ9*2u2+gq[DObg-iMTr4@iceERD#EANKb0VC:S).pXt+Y(Z:*ZGGo]Vc%Ad*A'@g>HFgWhYb*/X9MB"tCU55fUX=lcpdKgc5ZbAp?:\b`3>qp)bdVge<u/$cfbeDU#4Djb1>O"13"!6NH[tq$<h$E-h[Zu,&7B4bW(kZ<`.$2G6DRuTa)+9KM[.@p7'>V5QJ@7@/dlB8.2uuUM8q3cca2@u2K%Z5kL7W=Qkcq&FDZ,jl_PT-'a0OPa+oYY9.Zkfh5k)fQOE0t=G"O^5H%I;lR0jO0G[m5S(eG_0[J/DoH10QkH)e`=BCd3)g-qpq8?kAJ7g7p1#&uip1#uk8AMo<)s(CF:M'tbg<>K.;;6s4GV,;0)3NN,AG'u:WuVB1gENQA-Be`]D'O`V+24chp#G)")fkhS=CET(c!nm4EHNE\F)[ja0h6>Njf24(X7miB+'Q[VX%JYX&jN/%fB+G#B?TXF'qX=lHmZ_EiX6CGpL,%2GFXrHA3PkmipU*,>KR+5/+]?N.J70X:C-]Y5`R9fL*b2p^(lq`hcai.\Z0P>W\FoS@6&C<FOg;W(On%q*+#5QO^-ho]1Y-[?K&oiMc$cp?C@e5d=N*^qm:-O]SNie5sHjk\Lb-k6WVH?g1Z]+mMGuE6_fdQi,h7&H%T!;'>e0Sd^1<Y;d/Cnl+&(<mu60e>V:r4"q/mKB&oGe)t:>2#0#uC3[W-d=48CT0R0+49j@8/?B3>J]7P_05_:WQ^g^'p0k0<ABl::,ZRV;B;3tDOf/.L5QeDU!?Ptr6T'Np<`a$QjMXB'&WH;)FQd(W(M@dAm6jPT63f4K[G&,3=F;D%>>/(LjiPk-CRZ5TiK2P?c/7tmHH>FWp/[qq/5.B>J(Q_nQ24W4.)#^$P[Gl8%$<aRu7[EHYUA>iF\.M_D,@U.ni+\\'Uq0JQJ0jKCcfDrWin(F3KYj1ukn'I,]*^1^0\&,,4a+t3,B/UE)cV'C(g5k3h0%]$ra[&6j#]h('_oM6iDc0Q_&N,!m[.1rp[:+rkt3gc;MLd!p>ag?rfot/W8XiuXgt"`DPWE'-$C!L#G<W,r.ZNOh^(:&Y$GCI+rmoj09li`3uRfW!0*ObLR#JTcEek00'%a0K2o,j_mqbM)n6gQ/6Eusc.)n9_SLDXI"XuDg#f>@=7%CUm-jl`Ut%jt~>endstream
+endobj
+% 'R305': class PDFStream
+305 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3315 >>
+stream
+GauHOgN)%.&q*PUrW2,+fZ]WjhJ[\_A\=5,GU?p9`t(79.>WX&N(JU%5V(]phZcVKU1.?V`@NMoM]s+U3K;MD!:1gIIN7s/=s3HdJuhTM3A-cEOQ0gm9g5=Z-Egd)1EWNC4ReL!i[B>$HM8G%iN2J+aS$T45g.c_^oGj@']D"[d%ipeKAgUMY?Qs)TUW=5O-l\$hTom+2k'Zn[/PjVHs9nSZ/(hh$*e42RJoHeT'_<T%io[qm"SiroI7Ub*4<J#OlKke[F[,<UJI^!4KDE"Gkk#lqgAn5"=N&a@Q%@CM)([R"YCI`-2\NH;2NeS,!iuo9Mk\Q^-NG_C8oREU4Ol59#O.f"e'F^$9i#]7Fd!VqIQfO8pO8G`MRU(aj^C*.l5"EL0X*(i>;^F4rA*@2U>\/lh.:k75hp^7RHGHROen@JF3#h*8PFPS7$SR#_Ec@Os3(WB,[AJoB%t]\[cTDbk/;JO?Dta<_pd?YOcRY[=/c#"Rrb[jaoUb+];q9N*"_m8:H;D]F#M&A:=;cEf$TD#DgH%n@m$.N0Q6KA6iPkE#g;ls"Rk=_peduVNTOTV=GTdh,hkRrjrD2DK$^o#GM,lC=(58e><VG,D+2rHI#KH=Ae2"H)Wb*=%-c8)t4Kfi(:*M(d<"=ZMtMr/-5o1k7oN1nB:t'>S9=Sa_+4Q+Na6/4=BF"KSMUq2a&.oqlqBcqGptWH`WWUcSR!EWa@S%c:a7DA+DBhB7;9I8-9FqN!PrK8+D`*lJFN6O;Q?3+&o0O<,)Kdb^X:F?o_-rkbIiqVTkWTXKXJ)lcbGn5'3A?_*Z:5`O4Q6kaiB"Ba/u<;n<4HG0n>10R,N6aba<iKI?nN>"s#X^b^Pbm[fQ;-f4Uq&BD3p22J;VA&1fSS0[D^g[FTPfafG2p4gMLgBA_P:<AM'mI6RdcDMi$./eZi"e.DTDMcdN25(XCp6HugM'=+mR&OCcft?H)-l97`l-t`hkW**e25.fm.d`4tIt1/W]0@c5k:I7WBIR`%NaL&#`d?ro-C+;#/XOH?dYnbV'pO6ES==+kcMi/Z96=ZC(4?emD]%8N1@/l$YTD#Q6i5,a=teFBT^-c4DX/1ln!Y;;gC4Rt@sciNJm)Y,3@X.e",o?r:67K'd4q.^bp?r\LFESflFtJN[$jYg7d1&Mi_l5UcLpP"?16)($JM/K3((q=!Se(fE)0S2o^alTMd;EQFM#mkL?(cj%ceOS*iGf%Mh_Z/To,ZX=<FmS$!QF9Kn1*#8.L8(Ts&63fH-/%Y7_!9:.$;YTO^a!:][2@LBn;$I,GU'?8;fP;]W@+X*Ue`Z!sS#"c%jg2OgtYc=&,n3Y1%SiubSmhNm'%]lI/C-5P[6JTU"7H)^%1RgF1ep;_N?2H;I6K+ArNkr8Kk3mm<Ne4cu5n]`@1opF$IU-b?f0Vq)JR)U-uc1%.$)g$3A"c)UM61#[0$iODn/7f1XJL#9YZ4'9r54h5=E&%'/ReOH1T.6[]1$U+PnG`5II^XH]BCHj,S*3%Y]m0)UW&RJKFH<#N5+[fYBA:L`?!kXIkinVI;>u-#Kh4d9.Hg@bKVQjSLQQMa"b34Fp"$F7b9^b"bqS3gQC+NFT/M8NG;U@QcZF"4T\\Eh#<(MNJ[5SMEYt>SkLK4mcWX/h\KD(PrLSmn7[Hoeh0:V#D1I/iC\@><@ShK#`sYo._pN\f;5!Z,6P#AA$%#ZZ!`M1$:Q55sZ"afbLBD>h3u1XfL9830>;lR3m0SS]a4QGK#4@gR)_#;25uo/FKTN)S?56&+LN8_==VXNs+I:4L]\6#KOgI1ei7ARj#CYrk(rrPl^3/cq<"ob(*K>ORi1[ZiGHEBoZY,A"i2X,t-P]K@QFr!b\ZiK]oO`XZ9Upop'p;h]pGL.#e$6]bAM!6UI5h`)d=D/6_3*3-X79ep4imhGYm7*mcBij2!3.?O%\j/;bthq*4$tLMZs$]2C/EiI'`d4o+r'$M'7N0uS-UK^q^%fi0njQ1oM8"e:msc5FfaU^2QbQmScj<.83nBOM8*t=g[=1l!T`^cWUe2=-WcpmkHa_+P^U`cajXfi;lP>]+B9_iZk`YP\l`umB,+81Z3oUYn2pr]MQug0Ym1QI&&G[ZFQDGs*=B-.F\QGB8N$]k`+QEHPn^'j,"=7'IEpsEdPDSN2\$6.egfiAY5M:7D[$-Z7X'"hiOIpPYe+/"6L=D\<<l.g(S]iZAX"E.k/ZCtN#[M^S&Ag9]JH4.Kj<+#qs+@cNr@q9k'lMu\)%?HV`a.e64nf1i)pq4GaM`?)_YL49@dP0a2(kN1^!#Ef7X!2'6t*YiCa4_)P.O0beigVi&=t'&9JK5YloPAAa9IY9);1jY*kG+L\iI4bX/Xsmt[[p]lG7X5r&r.O-d1#5jor>n(A`XP6k6Q**n\KT`_4Dibk1[mD]oofe?ZL0Pp)CS0Ob)B$=Bq:ZZ#8Jh2p.gUkYW+Ft4QlBb"e_<0fBr3!&;=Z30mcbt3;6\)OEq^p6rfiN5f-S(9O)O"Ma.bVJL3j9\RSi`7,n#fcDP/Q5lPluV3?6G:-`moC-jUbH,Y?7eRYtAL5MUhF#20oBMg'^EFA9SKP5WlIOPJkA::Ffk6j=PK>?)+<Rd=R&7SBl7k-s>*&)jTb^dOrJ\fF`ehiAbZ?Y%Sgp)Mia7jh"@<-8,pVD\Q'V7.5st/2`>H%hKqDqk$X(OJQf4Wn:+qZo]R#.T*+D(5Gn%:9s1:jlpruG*g:4NruRMNC"V10-G*jP_aD^Z+_K).ZRdA,#r23(0cEH:Eq5Z7Z'%jmUB<8a*'[u%:\\kZ*uf^O9m:ThpDDER[a]YQ8*Oc#@TUG[dWY$)/:)Imurhus'D@GqonIW\g;W.&Ug6j?S^=H@M&VJQGZ-$p+DZ%]d!dh]Q)R@:eE)nNr.T#8SjhX2&k0'nLVY)hVYV,J%a6bV+ES!P(Qa!*+`7rs8)PQOL%-GC?^K6,?sj<Ol[maKp2U,\=I#?H[@chiU@;JiRq@<&<c;gc1Lh;k$2B'ruQ57H_/c!7L\na0iQ.&a,2CZpROYfa$J4A1`s@'$O$=V-F%"?Qm/D@%<WI'9`HQ]&WAu30NOFk?0B8>K'Cn_[Z0[jqf'FZiT2).0ZP0Xfgh-oPGhMjllJHJD3)TRJ1YK^[Jk.j08Zp>a&0%R2=&lfcNVZA-+]J*kVJDu*^1L2N^;'e:\.ai@=;i"b8d&pa5L^JA]WH1gHR4kaF!nZXH),d<Q0Z[0iqs3'Z/$f.O[Gr@:ieWb/VM(fedY-0p+CqHl93i&E;($o)c=YHhnJF'stAX3W@*1Q'6tRWWY_K@jd<qC%Y3g_[_"klMi?.(1$~>endstream
+endobj
+% 'R306': class PDFStream
+306 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3224 >>
+stream
+Gau`V=``=W&q3VVrW?p/@@\tV+t4S]]]F+@1-7KCf$;Hb+".bb0LHH]5fr&9^YJl#:t@q)S%'FA7sCa*lg>:f?/iY,=+="d6Ja<8jJ,@QO"=>Mor1_&^QQdZlW6=CQWl*RI,]E.$=HYJga-I>)5E<MFhN=\]RC#^h,[B@B44%@3H8=3di]_i7PmAqNrCQ\jMHC6(4VFb5IC.Ao[f/d_f,Fl7%SnJR_pISRce?UX8_>$`RLU81,R08U(RA&T<DT:i4V.AcX8l2IP:l9E\a31W8k8f)7f%#A6dNN25MHIEl]Ffj.s1UV;Nds6rC4`U66u%?5+p(hTE@fUA1-i@uV8ZZ)ObokK+u\4-k_d8_T$B-^(U!A4=?^p#r1e$o;YH'21>bSi%Z0>6Z/Tf3YQ:81tZ,pO&nZO#fQk<.ROA4*j[;X=I="+\<l29R.4ON2SL,fOI:UM.LuH9/\Nq06[\T#=g/3cgV>r&g$LXGXA%JK;]TWl'+A%E8G/1<XDW?aP1X**ZL8R,A[D^r\IleZ.e>c/8lUBQe;`MAU66_o8#GV04fNT:;cQ=U@LLnR>cua*'gXlc;TCobnq[3#N]l]<?J_#ZhX60VsX>4(Y/2JLIEb7?`YXN!t&=)4f=oE^-hk_fm6QVASSmU*'npR>_:X%oq1/i=MfS`kP_VQ4q7JSl'(A6nKbYSa]@utQ@Nbm2^WUK'OY4/f'2peeU#D;2Q9*d'/`XpnFjaE!p'Y?er%>NOc$@Xfl?S5*kV#V.!fgT;NV\JKfWV^U617rdBsPON9N<dP8JJ'@HY-1cXYd[B.fQ5_cd#mO1k&Y/e-V;pO^_2ED+6-<#_\O5ZW`D9UI##)G&!rhm&EA>dC0J@%ARUB`GQ),0,+k@u3^RjQaXt7QM3#Ga=I<,HG[D@-s"2fE0,H.\=QrWJ'-N$h/(P=qNDq.'?Cbhc8_&Mc:tV]P/LQHn#D*SAYbn]\,Q%_'Z>+H]aZ!AB?W$`=He($a-=Xc)@R*^L.E@CcRTsPcK$\)+rpS=)]`.5^I08c1#/B#j;M*YMaL8g_Fb.%CB6-gG'&l\Kqt`2MF>=b,UhAMNh$*@!ucbc+7AX?mNk&3#+*cNp0):d[.FT!S/+[,.P.AAS#>l422eW#X*/>gd>]cd/!;j4onkd`t.?WnE5,I$ZRsH&EjO7[)Sb/gaP\1p0]kVj@ZL'lq#%]F+?9)Vb>bBOp3P6dik(BK`udq3#,o4#ofZM!V1m5aQ!?CC5O!(NOn(8"/?`f</J^pUcJmK(^!;af^k:.GPn6Q&[b=k,ZYg2TC`;MW*<9,*-\jm^L>;?<3-L9ehB0SaT@Y.RYMr!^k[N'!,1buaQV%)LN!?]`n&RKBk$+9KP'!naDCW1@1pLEL4M;j!7'4L#1GW7U\(ZtZ8E6Uaq\10!4A;@a+XX(5Hl/`&Y>=,CK!ifci:^_B]W&KFCp,3l:h#YKbB&3Q-#WcKYtXn8)XGe4+SL!Ap;'#AU@`n4/=dA%;bm^Ft*7B+e`8"L>.WI+D:%($[0,_qbEeGKQZ\OkN5me3q3(\Ud>%R`J6G-nNY&eW7gG.)oDRU/u.sXMB/%X^eeJL`TWVNj3<VNfS1akZPtj.d&iGT%aABm"mkA30@lp&>RSC6$]"g#;6-`rnj"t^)\n`E$8<H@_)?hbD,D,j>#KFsh`ol93XtPh$+.]d\?kJGl;:hl:`ZE!ds\G@1l4'+F'rdj-4t-Tq9V&1oP3rh4YlZC@/qP3[o4WPruI\:^qh+Kepa48WB5dOSFZ3:Y6uOp?>8<`<TFR?XIWmU)t9a")J\nFU(`'PF*q2,aj'qENsmbkjhHdd+i^5Z!UR"CPuUOY<65ce_Vti$%DI[g-8HqsbWX`&T't<-kk;tei`4u<#YMH:3H2@[&q.A9c+R%'p'p*XVM/R85YX&_e-7.!)'>[[K<,raDNL;"N`uHuYbN>#!`dcm["PAe\\[-uj+lG#3j</"!g:-JP&h;o!ZPPVDg(t&OZ'Y)?,$EB1r$s=Pcu?t>hgQ-E1ri5VtnLL[33fBX%2e(D`0[mm.6;jAGg.V0NI!KlngVgfn9^DmAT=XR1_Yd#'m>W&)n,M]AbgiMZPZ=,?pq?SEheXN!uB`!A;qD%l53L_HPXKq@02u4Qfiu@53;0;Kdu_oaoBX^n*kl#Yp,`T`gd5eSAmO(H<NN/NuJbCsH]M_jW-bXeJ+#WmTQGG_Ts9:#^6sb8KruK>ak:ZfZl2&;oV(Zhs7hZTf2rmU?P["6c0GC,=YVBm:`cHIU,l1-H/()o7,pH\DrPUW=A&jQica,Ekhbgm4duV@;%SdrF`9XRDZZN3NN,gKi,:M9]bih%ah%CNbS5"Eu6tq'%;co:UeQPKU*r19OH'Sc3T)k[=n&*-#PWR8%OeV_XEnP\'U))h_c`]YlrIDbuALD0_G1D_]U<L+sQ^U)S@g"e@RSb9@etAounBNHtV%I;<L<FAI0Zen(h``__VPD8$/H"dQ=pRP;-N]4:DOg;n'e^kJN:FnL>ei<;fY=K,6?$hoe8^[2f9_%AM]7.MYQFo[IHEWs?CT^[iAiZ%#t*bH+pK+Sg8(bZ#mD+8\g[`+Pr8-*<CAhN4CWR@#@aaa_%Xi^j\W[(A6bnXN&MG7/,cZZ_-WjC#*X2BgaX0mD&)kJ*,Mlegbe?G<foJ'G;2]OsGpD]R';gdR5UUr`9ckF^8bR0)9<gue#cJo)EMjOZY9@p1P<b^+`'3]M;k=JB#dGHUl?[_eIKmpf7p%%M#jh:RNSK<$j5&0N]7g\CYiLK]1PJkZGC(&5_UG!6V\cu61*L'b+,eUG341cNb0+r69DL72:9ZRFmPhKr)G)kOQOQr&f8Q`=('k^@iF^F;_Kd^&u"k+7jRhY8HO7AfPaO,j='g;$jXs7?PnUH+QohmsZ7Uq37pr@e.P[5+Cd)6=ug8N!tKM?H>LZTjeVIP"D^YNDk.5[6Lf#&9mm#`I5)G%!C%T);#,o'WObLB?4o.sM<a=lbt5JTQ.re\_q^R0'*h]'d%TJ/1%F"VG0qQnJU69?Z8(Y")IauR-2KHOQ=&'Cnbp@c"@#]!q^;U9[6CnoAc]O;^u@6Ls+B4#/\dam(<3H3.$Z3QoLg3ht_#A8%neDe,D@VKXjqKpq[g=,3U6&g:g*7p#4R[O/H3uY`-qqaJVb2]c4SCHDCm&W_>]-QSLg.>[H[-)8fS0M52c@84iY&`s5mV+Ckp:Y_C1e0s*4&N?/3g6O%jRoSR!D#KKNW~>endstream
+endobj
+% 'R307': class PDFStream
+307 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3151 >>
+stream
+Gb!SnD0+Gi')nJjr!/1X+7)(G(9'7Ih\99iFVEN/XE:>AmlE938Sgpo+\4-KYJ163Jfsh<T;/8r4#'/dqo[a6/nc9uiEPLF>96-"QK[[)8%O8;/#3]`+^0=[ZfTq#?hf\R^dgb&(trL'1qEKElKROrD:0Ni`X(tg^&bCJ&2_e[a!7t`OKNB'%/cO3M)JfeqtrNXUQa(S>5j)=s5;=Ti]geuMk<s[-55cU1:lD<;\iX)g!()mI;XueR?E^CQjmPRV"K_@Xr>1oqb?43g6lF`47F7po;VF9Ea2iGH+%sbhqr/>];rp;G':?bI]0MR;Tfo:Qsuh3O>f0bli6o=rtl!pTT.o/oPD)N7b5SWR%U??$9&gTpt;o+EkJN44\S0^^b+iQM&A?bboq1e/SF0IWE2idR,="?ii?)o"@2/<Hh],",#1"TI>mB]L=kf9LS.B&RA:X,dl*h'/6K%P^b\=e/N4/6oXk(oYXE^09D!m7J9qmI2?F`$S^e'';2EDna><4BOnifS/n9l-+(8V'TF7]QVC:5<*QrQXNEBhTZuRj&!#GWYL^iYn7_=XiD%n3dj?8&e5Wn_7^qr7X-XkrFi'ij2_/D4["O7%lcD67H$U!%.huJ!/DTl%L,;U(95UQCR4rF&@EWYZSML:TY2i=/i=1Tnaiia-SL9Ldl-d9,\7'=^TB&'W"%JP[5!IHM]-_8QCWR`]9GlWn[\orOBETEX;G<]A<+-qUABQSnYbaCCJ1gPUUe4[Ym?^Z3MK+Wq%N>^A1(.::GEZ@aC%Ae>.'qD]rV%-^Eb_o_""sALY&?/7t5P^t.`,pce<;BW8*q5$bGqhEj+^-V*r)cUU$;QfA'*S"#iG(PH&0?r"Ts`iq"2'Y!1I1a$2SbRAOqO>A$rYuTFT1m$g&#jEqmG=nd(7!drr(.b3ZKM1TT__U@5o->KB">r@X<6#+q07eUMNH@9a"pO8bcgReagDU8bQGgFDI("J&76-P:hpNB?-$+[u53=Bi*E0ZjhCEZ<2+lV2=,1PqM9n1_K*BB=BF,c_(JHAe=J!!OSN6CU[&uCa[B'#l=Nu6T;C"dJLB<g!B8jfg3/'\EG$c@(nTD7f@L2^#%$7NQK=G7fgp;[eU^i[Cq>"JGL;s*=l))9\4uWkWf8@X?SCE_(9I)TiFX?s1`=E?jsfi`fUAsAq'K'[eRA"h_"/:jiO<Z3N)L1NSrc@agBYi4U>ltAUOMV8CECd^,7+[QO(5#XH05u<$f6K4@B]EhLGB@*=i6!oa(cQ?Kl>eN^r$MG?o\7Z[g/-lU#$ojN^e9lA*Cn^:-:tT#'O/`VoJ-X(D2P/hHNMDaY[C0B"[W',RtcZfsi_5#3#[%$<9pns>CDF?+dLn9CtQ/PhHIT;@([d_/mie+3!r[u[lbN)(7MQ2\KS[)(F3EAa/S%0iSc9/cUupaKC=Kp[V.cZi5YV6X?4_5"f^(7p==5rcf',F]33^gV"^X?N&'Bn^r1R]he`aW&0t:K+dJg.ms`WT0-:j?I/<<1b[CFW#Q[b!]E#!Y"-j`\3q%A5.8C\:I6bCE`Iq&WNHdR$:N<`!-g>%kTP14hn=,-BO40//tlE2Vu#[;c[jr^,@kVH2DIEc&_T0%>@:-*rCSQipuXIP-\V:ToIg7Ls6))K$(!b'HCr_AlgZ;P@@mS$@Q4G)-f2#:hF_>Jf.g44F@o'`\;uan:4gkMWT\R+3%]i*>%F)*Bo:,>gq>FKe+u[nV(*SL]G&k+%a@n=d4cS@_qn>1.nlM7d?#f*(Y5r]&g'@N/O%\6),1Yk4!FOjC+F1aEeT3r7jscL+u&3LU%T)aIsR2'CIQaJGQ=.*@9d-^?B"MSiW,BAp)?>9(o*"f]j?&Qq`U10t6o/Zbqfbp%/1?E$Sj^Tr(3B7eD?@_W*HBGD&C-YD5\?-7P+s[E&lu9Q8rpH$h`DdtJeC#G5uAXTBFliorLJqCCjDi:Wg#f<RFj355B[X$/YEL;$:,-6;Sa@;EMn^[P;n/g.CaDqSS8-Tmh8eBWcVR"Wp4QlecV6L@SuhEjW7"ng.L*7i/\!lRi?BfnJ%a4/='Cg#"71s+YLM9s6*q!B]'Y7:os8_GM?oPW:O4jWIl]J\@M,9+1t6h=r/Y%`e@"Y*F$UIG9VLu_9:HLW7TR9e=!#Wq%^G*e8I*@^O^^Vb9o@cU+aX,a^UO!i!)oU#1(_p0I@\Vb)YKQ.nMchcLoh!rk.&E84ofkuH(.GM?,qcs#k(@,5SO.P^QHp#X/klKJpr4PYVVhe:0+<p/d<ZM7FjRee9Oegsq-Smpu>8u1F9$ACjkgh+>(DjPui?l?B]MhU5oI"sXS:#W3=EW9aemVQ+4e(`@f/BR[8Zq]un208\g[kpH0,@-/5Qm&!f*&(f([kLKnAlaMEI05f`lWQ5(Ho#"U]-@YYi"`7KPgfE7RdE?]D#bXim1l0%$1HX%Q\Zq_Bqdk;+?FXYc'i,7Nqkj*6PY1&]rb6E*oBUp)[+6ebH'Y`<#4q7!LIjegCP63Fk<O;!H"mD2Op$e:s/tJ0Kb(D/r&0'5R)4UVQRE;HVKFW"-cHin_9qUEt=65`p]gOb+2f/%$gPZ;DQ1+p!Q@b-]8&'qSO@G8^XnpQ37l`^dEb_Y\^X)#Aqt7Nqkj*/'@ePk\@[:!o/ag+X-G:ukHM9o_bm@L_1.'\M80$EG'eeY5#GIY6q-=BV,8\O`:e-\mOC<,,;&@"T5b+C-Tt(U]>1e0ic(N<W6s4d';Rm?9"&?]8>TGo9B.+C.qq1LK2SnV7J9Wjc`>F)\^h;AQ*%nA:Bf[_>d53tLCS<;W<q_%r4N2dV6&jGQHl;YVAi83U!D=1qQ`SUnbS8m.B2_$a&3gA4trm6$J?;<`^*"C#DT!PAgd$'/.e)I\'&bcWE@Wh-2UaH5qL8u"pNJZ>V`XK:R?_U=CQgt%WGIbPFe/`#SD6OF.)Q<BV[2G,a)`"1B23R!SJTLPZ/<P;UOAMrolQKF"(D66./`JN6mngb,13A79D<m-"baj*cJPrd"q4#nsl.nIt$"`IIH>pl>2jYDH<gFLkNON\1`4FrXU-7]F_YZb5mQfShpT2\JEj)2N(d&7Q\;Y>(,Q.<NO==OnafNPj9S^U.(Eb@5g^9B:s;JT10jlI*lVI..$,fC8EHPKSGo4tQU-'E)$:V5!.2ua&mKGOI~>endstream
+endobj
+% 'R308': class PDFStream
+308 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2527 >>
+stream
+Gb!;fa`?,q&A=tks3RUc,Z?TG;O`l?ChFW`ZIHg]_c5_!OcY55";lZRUA=ZM#!n.#/38u*@P=u\@d2L(IR$+CKJ%_.mb]u-\/<,I=!<5/N2I6\K0G7O_TVJe#@H7fkaN+Z&4OEKJ:0>ILN"/4c[o$'(IeL/5(%mUL@ms0i+tB'E=-+ki+j=)AfLsVR^26CbmYX&+2dk0N.6&Xs6783<58@AD9Ss5Vm0ptC'6K]P?3/<]+.K`5Z7:A&VSSk/KjIUpDB,\4"*cK7Z/P=2Rk/g9S1$^?[fWk?Ghe:0Ha"`]0VcI_U`nus)l6UkUbr*1&i4-90$YfL#iNA?@\V653M%"T,ur!<oc;Q3D\G::QP$'b@/C*2sr-'Y4+WD3#BATc4(#5hb&O[?OC4db#N=F.lY&aGV#^9L8d'jFucP+0GRh>-hVHVCWs,tS5A;9m]Yq2]`0[?#nC328S6Fb4O*F3f\?`i6^p0.:QL._6P.'Qo(-L9i/g,lYl41RCN?S!XE*/in[msN,2nt3%_@)_R!pr"KJ[f$V/50R<;h$P1g`\(B_0dN_+qbDRd-2Ys1@5OZg='hG8=rDh/0h[9A-1&b:RB<%XAI[eZFC:+3tAAHGOeM]kB@TH9i8;!k;,gAcc6&1h4(`#V#=E42)gVqqXDgG/2071stWtUkt8rL]OSI?m4.;ijmtT%T7)cjm"\R74+-1"?)Yk4UB:+$."s..puL,7I6UKU'OG:b@B-LiANT'Jn&_\L#K=J)"#c,HOektF/*Qr&rn"Q2]sct[F,9V9NF.<6Gsj3MC-`$e^PBckkJb\'B0b6,iq^FU7nQp]-8'&#r87l,!fsB:q>X,+Y5=%6q5e`:qo`J4P(`9#0:rN0k;_oAL\sbNLL2IKM"k/iZIj3(1M+h\d>Xdfg=UB8=@9@nb']>Q=l4s?ZS5]:Og6E%g-)(\/1[=(I5B_>$F$I)n!-HOO4=l$sP9+gqE":()_!?S>?qqcP2+e:PEho<(/jaf\tBr'>!>s4onkqJ/C/eE2hfJ&km=e!\s[N$)?B7Y/hF^4OO#f"Ob0HG*kk0U1Ub:XN''OJ/<TC8Mug0Km2^0A!14I>cYANmA:W&'KI't.nnn89[a/gE]MM'ms%=t=apB<09JmIqNZ9_*o"k+FST,^-0Y9471E7g3Z;t8RB8.In;=O8.jJsV#>?jK53H3V"HL;tmI[7rRt3p"^^$7f\\RgXg8[l"OC;s&=X-U\RPBGRYn8P2r(P$fBSb2RG)$@rqEO\X:?aI_;X,P?f7qOl_F&fUF>\'@bC_9cm)nHQh.Zhi4fGT7)l!9b)V.,!1c9r=0-5NK7jDX\=g['^V/oi:l34XUE%,pWdiN85HR+'T/D:K,QWOm-L>"j]ikI%m92F=0ToSt>%Via6f!rMJQbERUiD/oh5G7j9\384<ke8D0bEN=d*[pG+pCl_*-Lmn^^81$aq_Y&E!EJCkPLl=mGhsK[pZu4<IEMs4cgS*moU[*c)#^aBhpE=J4j^P)T'#;qcZ;3J[ccO*eD44)p9j8]W">"1G!W'/('ta/bQqM,=su@E-j;S&RULX.j:i47[SG>CXI.q%*R[SO"3&EGWXGmXN0k=T\h*2m*VpZRRV@uWU]W&MOW_Lf(5I*tdZZ[q\69KhOp-V9D@567?Z#GH_uE/UEoe4*J?+*EM_E4EFoj/%]nCeV6Jg2.K$mc70lqt1)?$C,96\9?0Tp[hICf-!=^!bLDstt#PEpDf%VSXLm92(Mk+hAp7;oN5B(K$RkXnk,G+n5EUUo;nFpE#(fc#/50LnWoYMV((XtXU(]n*"<$*J6Uhg6;Wa._-L`u<a6#[#SdFe3:7PNKZR'G4P['OeeP6g_=!8YK<t=Mm5nm=5A-EYL3GB6"6D%t992*7Y,_#BZ+pRV>R3iRtKRn'Tp/Z"aJ?]=m7[f%q2gec>`-\?)&g:?kMJ2bUc.kYs>F3?phbN9$:*A,$bK=2cJX>^M=]9:7'S+K=YSGmRPVRa,(lg/>O%)H::VcEOq2Kg>ekH-r$kbKDRe@8C#LoB1mKcug0D?L,F$i`Ja5P0^WOQ-,r6f<4"%chGXnG=49sARl"/aXQ6TA?2]WWRJ!j9pP!$ZaNEhDpm'mQKp!"Z+^-tW97V6BV[Lkq5ZgR`2]P(oL2V5[M5_1[fVDj$jkZ%AERu.f+=fX?=)&#KUEHU/Eam,M;GZ>Eg(mgALXaJ2\[^P>+gMW<7IplD;lO$8q'<ZCnL:WE:h$]IXU8K*_j$[qVr&'+%G..VJ;7Tr@f(sfc+8Q[dNI@<3>G]WXi(j0(0KWlWP^NXB^;aqnd$4`6@@*g+f248`s&lIQ>.=n:#d)I<e#*q>/"L^Kk<544XkEn!ummZX*NZJD]2%](:-BiI;4BgON.pf\W@jKEdI2@+[KR@5GKkVsKgjWR\(Fn$7j01T&)T/k(fU;:I/YN\!qK7hZPk`h.R#NF#9Pe`D\-`4,PK;Jr+H:W"9VQ#Es3\MZ+@B2eoAHd'Kh@,gVFhQR.cajdC7T>qStPM8fr_qPa>_[$2Cq043.~>endstream
+endobj
+% 'R309': class PDFStream
+309 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2436 >>
+stream
+Gb!;f>BAQ-&q8/#rkgoLXc8.dc0h'>8_i#p)_(0EF56"F,U=NV!<iJbW5$'Yi'ilA8!K4/M8lhQOT_nTDnfR/'L3Ue!rk2O!DZ/Snl5ZU#bq\/?.O_W'jQ]h5PsMK61K3'$Xq*\4WLeO4b1GC]Z(0C:([-WmeJZ/25h9/YbQXX7O\H@_qR.8XZ0]O>-dOFbS465(GP[cUEBF!^\QKZo$)+IKc,R"D^\>i.8>SOXM_UX:6"CU`3"Ybjb.[J$Y$9^fKT^F;\:+#]-_d#brSSc31<DP+3qE:9AoDe+sZNO<YgWbQCnu&R=KS"h*d_HS;)$[@3gfl;O*^!9r4DN/87cbH32KQX/W<Go4_gl`-9uBcj$SC3<*<`Keuu03!CgleN-R4d5!nEF?2p;`ef4J/7aET?,%JAC-m18Z8'L-]3%[YlPa3pW/`"b:d:`<7WKll0!.Ja`I].Y^i)KD`PP)6N^\m_<O1#0_t.4Xeknn7H[E$[IdRB@o49T[XPN49O,c,g)RS2UG`[9[c]/2E+:B9p6aFVf#)-7e3;N4[c3dLm7(Qr>Bm[l@7e$6m>WrA>DSZ*7",L9)`M_pP8B1d*VNb%YEpYk_(@i\<>iBUai$C]tY-EHl]tKN4pR]Ds%H"trr$+l\!fNhW'jP"W!bQS(M-u,=@mJD-,:hj95cim?JXW'A-CortAd!`"]-`EB0U's'L/]_d6H+bM1:T+;A<J5fKo7(l/M/HHRF6q`/e=T\"roXc$6t(Rb0mOK'O`@HPtn18VK-O3J8?R&@ck+AEdDG<?^-9nB=p8)je09K(&*>f^?UqXBHbIabHkR5+.g,,HZP"L%%7"ZMT72R[2<.D:p/S1+ObT[WmDmECN4_Lh$d<X,`la_A>E67,iV*9]lYrUoCi.5q.d?Q((]AOU((tdRq%TE]B0.I)hcrIngee3QY`Fk,X\"$S'C-M30-%PA#U+["[1pqC9C:?]hOu=8i^KL*eZDuO%GU/r^Un6DM(6HLInSL&YC"V[G[@L-_<!8ZY#d*1dDUC$]:l/'-d>ZC#K%I91*E`F^2m&_!j-en<,B(^qmPVq<%8A70Q:6E$6SR]*#X]_);@C(fK8<*?.1ULtb&BU6Th4,#M.U[k5^`jCWugGL`E,.0^4gA'[R/"%k%37,q30GQj.?R%QZTd\-%A3ArjsFD2pR)>d6JDX3tUPN(HQRR^4e0ZRRi0Z!p`/5]f!PNpb]RbP4U'K#"*QXL'b*5Fm]s*97UH-S6?>BZIW,\G-kJ)OoW*)BR&F'#a'XM<)c0C5lB6?^l0"4pRBhl<WjdT@Vi(W';F%-HVhQ=67"\pH9dM=82,6Pg%M).niKF*1g_N0@1'&P>>GA3m;H(0i2V=J[]f2Rgs;SlSnD=CN9dF'q`8!K462)0GI^^V:6/?Wen<#Uh`"g*9hO91TK+Eq^en2TYVM\GM_7=67WZ\E9VT\(fYAqS_G,+UOa*=_*f)\#\<kpQhgUgD&153G-_fBTBLQ^2h9%<&3RW>%MsPj,_H-Dtj"70#OEJWnKT.2qGK[*:@lmj'J+QS:]_idhE+/#I&CVa86k=J"uT7`W*[)2Sr@sZ&A=C\Fqf0;<p2-p#Dn.WJlr&e43qj;80NIM=j"^s8)"i\-W'p];GSWD<ibh2m9FC@L*!Mmp_!rnNP".[mG>s"Q=5F#e-+<hm3VA?=2gj(Zeq2#+O_$^q9t?]9?MoJpZWC-AE%':(<iAW$c(tF00G/]#TapNZV^mXJ,`M3l?Bo<RF1m=Y+\u)sr01n>O+J*)ZDbl9S<K$p;Cfe2Mi.<<f#-V2\oc50iu@pW-D`>J%;qlDE4H8LHPp3@oKP,Q22uDR:)QY'6&VR1#Qf$>tQGTEg,)8<$&NFIYecm:79YP'UlQQ_4i7[Z_,rh8X.5=!0\"l`_M6>/aU=eIFL9LS+%kDr+O.V=g/SP+Dd*L*oRap2\gB>1J'pPLnM#l\@3:`\U!(KqblC_(4F1Q#qu/X]AbX44@>!J0P.%:-CH&^AG>S-9lqWrSlX_^nT0)1g,E,Oj8pSniI9uS`n@"Vf5WDB\d/5(@o_T6uYt0)<]pf^$s:1R7QI"\KqB\l."Jp!H'Lg*s]A_#(MI!'2NY$cqi='./D,3YFe$XH-m>aL7*a4OtakW'T%fF<n@s$rem\hFD/6NR[SS6@%)H7M[ErKisVh\l1RWZh03?+;*'Hor*>2lc!GUYE,4E^r^JLpamr3f9gsC/8(F_HbWj:W@VH+<B!jqFLG9n$_-3pdT3]mhT6SlMKh"V-*$pg)"#kk+9P)(8Z:%UbitC=h!MgR*7KFu1?])(3,Rt#,%Q$^t:=n`M'ga1Rpl%\.(i+`>q*Q-(ZlmO],Hj&?T5JM9QblY2eZ%t+;n)\EaQe_OTQ!\q6M!.2l`8lN`94j'MDht3jW7$A3s7R0N;r<ILq5/,!Ud5?1s"YOZ[VsU6Uo<~>endstream
+endobj
+% 'R310': class PDFStream
+310 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2636 >>
+stream
+Gb"/)>Ar99&q1@Qs"FreN`%9@;'^9E3@J:UDW=cXgIOn5*;*`//u<E0$SQPM?f.8WP+o+V>R*iY^kOF\Qb0T]HugSCkhqMqr]1(q`<=K#2o+Xo_umnd(/.2:20o&ZKDIH_l*^cO0'h8:cc1)0Sf?cKf'etqf7po8:N0=/g8N=%4W>^K(^@ld>b?3+1Rki>W1RT1Xhcf\quN""eaC2Nh[eh(?ab[QGIk.^1MQQ4glTqM0XHUtPD+PYcqP_K_JLhj(e8l2#`q@=Ma2q5cX[_VSr+4;SGT@Sr?O0i7-KLrL3!pb>_W<cBRPf-W"+=N]if7+id)Da-YDgY`c.Vq;VW#9.`kj&/qh,^5JV,H$=T0M-[7+R^*j#!iGPf#$9sE!K+eE.+r2@rjUq_/Ba/9(1BCgHi%XS#'/s3nR0_Mg]<!)Q,UqN]*Dbmp9)^X_NqB+LH(8K'huV&Bl+7LP,mH-#M3UcRJ[UYM0J4.#^;'O5&P?m1TkF&e@HWBV/VE^)V=#7f6dg:Wl@T2@WR:/b_+:SQBssXRRUp7hNjJ.o$[i1YqO\"VApYi+b*dbt:Bg#WBaS\*A4EO]X\CI*!]="m\M/b1X`^DS)4FR%`H7Ni@'W%dlK)R?ppl<[_Un]W77O*Co$AQ5\1b0'i43gBaV4O1acCZSX]nmESWU`H8;a/)^K$F3Rt6d$=VSqAMkd%ae-pI5Qkuu_ma,p92G12?1N=2b[k$NGhbJ_!\>*5B-5LtX;*6s19u;'n>VrKRVR<+_2mMM08"]`Nr_Klh'H`-CO3V30h@#0*#=q6&,oO"$[]5t2U6[QaWUptq9NsEGZVKDIkYLI?r6/anR'oI>bWigl[kB61Ho#WQ]6Z9I^3r.mp4C#<DI8urY)4kk\!L0kkqfglDOoa?Mmq<5bNUgqF<72\[>N9eXf&:n?;5<,D=HZa[8Zof3:A)^rsm/'l92IMOIKo1I0!jGnO2ZS[gf@"^?jgO\VnlSW$:CLHE#UF(t%`Jd@$65jF/^R<nDIkEhLpi$4&a*^i^@@2j2-$oN4u5PhoNI.!p"m\iLp?2)Y]ODr$Thm(dBFRIM`$^c'^.rD(DEA9nRTpsncdd3W8eqpCt'F?R@WfH)Zm-C&3f\=G#YZXedidIE>4om&OCd;I_(>Hp^C4E=`]&YbIXYEW$6JP1<0SgS4)IY:S/&k]&)c1TOAr_;0$S]rB7?S0qNcVlTjIfuR$]7*FEY:guLk@nF\h7PAgK5Z3`qBU`sNHboS%H6<;!Nm#"GM$F(IdN:/j24=/.K6+Oa-?Nm+iWicprg#mc!q+=\dCtOTNh_E6UB.Ts!nrZ^9ll=OfB*KD8WRrd[U21GK3R\.M)eC16_h$o"-bI/VC(99dteSH@&UN()Z4!?Xo+`VNE)`V&4D3>837bWhMU^o7Fds2Qml[L#(7H?uuWi5hCA,Z8E6`/nXb,<tl/T)t\.KF3K*;TMh&SK><ANaRad/6_da/qYCd5)kCg\2b/.$S5PZ$C7onZl6a_g]G;C?UYng6r1B.G[?RhMoZ-DCj7B&@)@slt2dfu&]XGrI=<_"@/cu#SnBOHj)9BL5m61TA]0fl9H,F@6bmt$&12Zs8L'9-*M-cc;<nFe9r!'/l;6.GD-B*u,"q?2Qe#MikFep_#n+"q.U`d6!-[bWgq3(SD=;WEQ>EZT^WZZ@e5o\M@hW:d<EK(.n8)[c\gq/KP]aH>(#.mJE?:PkZ(d'=4$gN0UXg12.[jW+ig_=@_/#cI0:g\j1W</"K'[3%0^;Qt\(+i^!5.q/r]gmCMKZ1u63#'YWKpf`lN%#8!iZE24an@bl@u01'jVd4=Yge@UKuTi8DVd'$LZX58V@Ug0FEFCqX\3Iq?GV\Mai@.#j/a(HF$*O$*7G)A4E-"pF2'\XeN:l??_hC=G`[@c@RLb0S':dFLl`BK'*;9.Y.IYIcMa:L'lA@#CAmR?(OJd/]=SH8afoYoE03P4e5LXLC.Dd'8a:X[(U?.#/FDs*NCg8'19ono&c'N1lBq7/KJLi`#Vd"_F^KuaE(1Mg]Vo0cp8r:TrnBo_P#qLN'f.W(/4'a_o+a[7#&;HRY\<Y`GZAq\n8AT\6PlPFGTirOHf[YZ7If1,hs/gsmCJH>:*N:H>[;p(`-i]uKUSLu^%ZV^of:ae\6P/j;9]5$<+.=Wh\:lJ`X+Kjglk>-c)3YTgCusHV$j7D8>qR6SsEiJgE3=ho-8F*-\UtVWHnfEZ+Um3XWd"5NuX/jYeJE'C$TX['X9UNp/PnBBPHqI<B]TGF"J!/cQ/i)XM?bf_k#fRZ]p9m]JQ\m<g#>D$+lMr"_H0_hQ!eq)U2Ko?`V&mnMLMX%(Q?4R]lp9B>E_8%rD/lXU)[BKO7,9BOJXA*V[JVle#6V0\@r[401[5CDuj_OfkX%$;t`l3&X^h\L=%iA#B:16H?kuFjSe+%bORlU[=uInIZ&uTM%>JeQtG^:IuqACdfM/X^^A8Zk`'AH%<k%)L7^hA'lHd`D\dm$0GUrB#U#(4(r1\bt.6%m7du-lA6O$@dC_&@\\QoB4,6\T50(p7A<#.D9"2>a"/*eM3QQ6)T[?0Np5'$8XGoZ?0D`Wc^YG,2#?G,\+UGjK,*NRCqU"85UoUdR<0-B]Q,1Z+0o&n\-FI-qW'<o-5S6~>endstream
+endobj
+% 'R311': class PDFStream
+311 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2626 >>
+stream
+Gb!Sm>BAOW(4OS'rkk/:XHScK;-/,!fi^8#Y'6=-CSfLNH647BP)tb*$\39)^OFK08<C,nMfR;"AB,UL";3]'mp$IB!<6O&5KNr?T>NUk@Yfdn?U?l8`\@E)?HsWWqV?SZlLi79L;R[__*'mG1%aLP/Xd,<nSeQ]O!!>[E?I)r:8\bmk7GZG50!2Ni[gN0aas?<.l]P9$M+c^J**^0j?C?1?[fT.bUaf(pG0(m6$sHeZ"'Irq2@9>jR7J8EYZo4N]#gs-0+CPH5RZRpWNJdDa_GO]RG>jLGs/7^bX(jfJSFX/:"Nq1(HpcIMeY4BglJr/V-4(2#\mZL7>UTVa[pLQKO@.]MOba$We^Q9\-uf>]NR2H>oHXYn;06KBGj1I-I2&)j,0sX,V)8D%^,;]uMHY$o/Z]TNs,^0_$"iZ=elO^tUY3Z=\-rSJ?%@gK5e$VGenQc@mu>abOPCn(De<lf_IV!B>VW+<#BbH]I[%L"[*hN!3WT.dM&Kq3jr$2EV%ekrC@N.i'<raM=>+bEo'0*0KoAIX1T#/1qeo@O8uk,cECF']N"^V`)t5OYOII3X>Qf$bg3lTesq4[;^3u(8Z.IYUk\6&hb5CFGf2b0l:Z#Wj>-#A3<?nPNO>Zc:cFN,QcT7Y2-g5R;+$GG[#+nQ`AOA#P<WZ4L#L2;WNR'=*%u<lp9o5dO&Q-LR8$cqu4VP:mq_JriAMaW8J*u)-`csD?N$h(9Z7/=YCI5$b,an1Yb9T0Stb\"7]Z&@giX#p>-m67ce_ONDAr'lZ"bKN2NSOHU*JodHk]3OlfGZ:`IuqCP-I<9d;WIG6)VaN`K]SE1M9ESAe?QIrOZ1(0tEjD4dZI13Mu8L\uU3(_Y3m+j$*;=/j/(1Wp5r`1]?U9-JQfMlkb-:UE;">-0X)F!4VH@:1PS+S;]7e6C<LFP8+SD?Im\;.O?Y8*<o02Xr;1+,SN"O^@(a(-0N;lL<g/`0A'Z78Q6i?U`b=7a*!Fq.k1!bqSM>&#:j:"+3?q7F/Q'3gh#*itj<4Vdj6XNt0-a032+Pb$u^9]K,p_Xic%83_%hJp=6`)7a1(W8\Fe:Ho=,ur'/ij]Xo[0$^kO:b.C0tnT9-m:quMfVb(?_6CL#+HLdK2-l89LZ7YQA=<4(FZ'<%m8+'>UTub1ElY:Z:\Wd>?DV$A77`m)sWh,TsjGTFjlHps%C7\o[K\P:?fG'!%9>RsaF>'`8j2"SaiiB>I.lGWPe[A4%Z$":!UpjW>el=/%b?+G@(#="_?uOiDYR#D`/FKDsW[d#-n-V(JWiBE-;N386LIO_YD,<70DXlffe%9cq7$a^Z.uX:k9l"LjEWnbL/?(=FNoPP>^3L5FY5e?Oh;k^H"k,@+6eU]eg%D$L1Xb-td;4%U[J`)pof5.F9:o"YKdDF_[pZ9i?*>VP^K&mVncW/sJp_6-TDX*h;Z6g"H2S>%5Vtl##7;REao[X_/.]S#eT=9"JY#B&@o3*2dcmI6_6XQ5?WYWT=6$5e;7Bdbd.@Sh!&E\2#^;"2CeAkj+Bd8s&p:Sq%XaX/1a+An`/+Y@2sH'4.nCi)VN^ZkIg*5)[SU#kD[N;t*ET#P0kJ-T?ZuK-)'1T%g=IWrDc.LSnlB9IF?,\1<ba,m/]Ls'X1GH;<7IH#9<L/*(,a+-;^ANLQk]R?C3Pl'QJH3U7ME^eO[T+-/h.[8Jo.@6.c\o4U2!(KBOi!*qA(%^IW4`u<47l<7!&Qurlo96Wuon\R`;j+bk(9aC+6[g9+.R.S>W>/O]Y)n$(C&5PenfMWZj69*J5iD6%>uBP90nXc54PYo2C_.`YOKZ?996@ZLQ^-e$td%Kk;6?83183CBV7uj*r8Y0sV(CMq+=H`u&(mPoSIq?B&\.SUBU$:@M94Y>4dAJ#clbE'(no:">C\3<j&*V:"XMaV3Ef1Jf_]%AO7Gb9Tf@:^3ebF,dg"Xu;f1r\m^Ni\n\!C'q'kFuUK#\u*<BOuuDlpLYZ#n?bcOW$VWl3>8E@=_9:N/k_UWeBrN]H.bqXmBuOq[@Pi6q!)R3Do>cf)`PV>>=JM;%3b;uN,$11<L?69OB(?'Y*aR;()SQ,G'65jj%!:?1jZqMbX#qX$ZL%-l`$ne$9IG1Lr>@qf>CJ`0Om=\K(fK@Ols"g)Pbf=cQV.U.&S.5]0m7D\NS%ZIA*WYB"^8RHJeR5Z/L]S7C[s)=6,%4<dWeIRID]B[4.7^guQbkp-M;gMR?LHC@,Mon^5IBg791oaeK5^7p'=6+1SZQ9V^KJ"MY4Z9:!D0QE5eQEMq0Oj*3KLIL56\rqs[o7hWG=8JI5*lSKMULts%TI_%kIIqN`rYeL+N-J"Cb?%b2u?p)Ng"j8g`,J<rmPL@$HJZFtN07UsN]@^<T/dtFiP>Lm2:fNp%C9Y7;qT\9No1^e7b^EU/_B>G'B:dq/GDA[N3cN.9kJZOF'^FsmK*d@WW[0q_;;#Y;)l9:QqsL1X?2%:/]0_j'-9r)GMA<OSPo;(QB:2*b@MNT#_h;V6_lphQ5[WV1l=*T5\'<e($f&YtXi5#q\5H:%>L!"+X%2Y?*'7I/F1XQP%^/SP]X?1eWl^\4T#60fkfV$)$@&/&8F>s*?u#^8J`S_?pBG]u7GV$gN[sVod=22T`7n)~>endstream
+endobj
+% 'R312': class PDFStream
+312 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2892 >>
+stream
+Gb!;eD/\1M&cNgos'ah=9a[:9;Ueq>PHWU#!r+BlB*F'bl%^"aP-u^J%!QDSs1U9VE_4E:6G"t0,"=n_q_C8)bVRR]Hl1lcTDspLJ0.h]h;<YM"'BEU&%rNT\+$lWlW9_Sa017o6O3a35/fOqpHDjZbr]i-T(p,9p9.i^WkR5$mO`$L=JasQ*e)-%BudbCV(KacVqAj*J,C'_s+]'rH2HLokB$7agT`VWJ)UpFk+#lZde!D<QE><CDR-e!.Y^%tG,'s0<#-ck/.EGe8r2S]9QVlp\G>g2!P9!\7$?b^qZYklfP,bp;t7uhU?5jb9VF:&%q!Ig,9lBgO7GS*&lb;I16n7B<p@iDcQDUVNJlZOp:A=f+fqK9$nc-\(5jAkO7+SDGakWg<Zc6G#0K;Cg'E?4q#sQk1)[tJhsJ)bZ02F%[euH$#Te>Bi[m:MK0N>JQ.?AQ.pNPg8G2NIGHY@b&C/:e+6&-/Kt!R)n0*L)\a[Vp<sdZQ>l^MZpo0^mn0VT@qsh%b4!nHU1*fX6,fXkWnM240dV5j?":EdK/cfC2YDPXbHlK,&95rguM;$&7&1+Ua:g>-h',B%?6c^Aa[%V'hl6ah-^L'89=c(<UR/Y3iW/N+1I[<Nj"_)9.0^@!>R*,&NH-jg4&%TpBNb:X$2mSM_5:'4cr[u"igkmkFG.;8,eER<W:`nU<X3<<K)9E+o4:f;]Lc?HlK9H,_<cUtZ;uM7/22=)o.55sZk)PV[7"plYnC3gXT>=>+GUrF"fb!"$jq6UGT5X]0VHb(@ChYoN,/Fd-q@nus#It:uoDGLFb!Tq/pu0\+%rOFLS"U&SIerR(p;\L<YV&pbY>s_4D9<idb6%6Ja4V\lBFV[siG=)^l"m-'AKgA!_Wgj7WfW?;%^9#XV_UG@@qX,6B3T]inrun7Xm,M;7Gjk5p;j#J#h5`G<Dc;YBI+Qh43!?@^g%@pTcXt08:Zi5?n1UF]S0sN=_6)$e(3L*`MK'FAE$NnoE7"s6NZ#c&q/]S0A<F#_ahVH$\REhFm1rS,.E?V/nn,$1N0Rh:BqO,:`7[-T&Zoq;B[8L*9s3^%K.mb"#u)liB7.7foLFQ,StPgfM+seU7HpDPR,_Thu\P2V_17)pL&"ZnWtL]qusj"=_n@cl[m0;YjQ=OQLT_S`Kg_ZU)4BQE%rH;0Y3sK/19;!#3"2BlH"]NSKWu7mk.W2fogWh,6WB^`,^#m$2h9&I1sYYS4:5ofV:)%X.XHXB4=5sNi=]Z#sQoG+L9#R`u&bH@&"?dKs[!:l"q+'Qm5mX+sZUjU)(e*)F6I^Ne?Tso7Oh3&RiU!&?jiOi,rc(jZp="+Zmj5f.A=^/02#m>dij0?+=pDeWRb>IsiI*S_7l-4/GaL;<Y6u.AL1pQ@>:,_QQn?8MU$0@JrVhdMlAs*YGM1`>\RK$+Vg\^G&#N4LgTLBF3\a2Yk1qPkZ6mT1ll]MhAYG4e>C*DjcG0l1tIAKCL[Vc]`^bI5C4bf+k<WbjETJ8"]g7)Fmog-9L"!'>5/QdpZ9]GjnI?Z63m*c5-/16/i`865S`O76AX583.T@.'l*p'-*=2MQ#+;hGaCoWM,M*Uf'7G91hf=7][$,Qj;*&J_R:`<I,!2%m-0DaN\s%N&!\qdd%o5(oKK#aH@R?9\2Jaf"&rXXWU#el?u,sXaJs%hMKc3Kpd):Udd"I".!C#2a4Eg39oc6Vop?U%52qOmNJIDYZmM'G7dU.G9F1YnJh4rEmbs>M4E*),-6kM\[IA6M[gpF1Eq"HL;R(gcV*RdH.fXgAR"';-=[99a1*1D)jdV__DGN3Lp+'(^cXaIbYd!dI+2CG<Mlnk(YJ2\A7<f97k)T>S61?J9tG(UWakDXhNOm"^EYTk.RV=D,Zl\P``1`7nl+<b'1^O>C]n>TXQ<2>.'1@05Ib<TenGS?\ZQBc[`N?DK$kq]lc&S):WOYCHr^G79@]Ym2"fN`Pri]!-4u>\etkNIR0Ds@-4bN;oZ!Uq@gWPITa>jU/I?3Q8VG5ubu'<`fZoH\l5RmG)RAusL:=0H&,KUUZ*PlI.egNa+7X=LjPkAQ0g_t:dN*UXG_0N%_AX`=>+pXq_JN^8$_F%gr)qr0a7EX/(m'$LDr!Htdur]r&XJ)#53EZ9j3sL/,GQ)]dOG1#:;O*+PF6#Q+uRj&26mA81Ku!8S)YI')LXRQ;2$D"Z(ZIs@#ai."/NnY>>0l,&<%DY\"*\&n>b6'8%4]Tp08d9mX9lHjn46]C9:UOU`r0ko)q11rl\Yb9Kfn^mbeU$dp,`2)/Pq[>WeS#H8&VI*VN>kRj7G%:G8Sb7:O89@sPXHEbb??g0sG#pXKfXNuQH@Fh&9F9Vm^sc\3ZO2r"WWQ)]MKhGdmjWYdS/GF!:^2+o6>#bFX,QT'kG6&sYX)i]Yr<QB9"O7']R:^?s7IfUF4%OSN$(mk2SQ#4jq_GlLaN,<do(PIX^k6";CN*qfF0_T?;e:odinK<Z.])+H*;-,Id2]RPj67C6Bj9f=ToV]Ma\@M2lQU>Z9RWV#Wh*1e@a9IcAH*%aR+[sr;YqD?Sk/`Z-ipN<>_>g&Y*[*ZrK\;?Haca[%p4"R5B39=3)u*SRci)I&58"=T%*8V4H;?fC2s_OmAO]bB\RhCr`oQ.\S^38k#52PYEhjA6PJQbHVK5n&TiH]3I8j)8ESsa2(RfGo_j;nBDSc(eA86Ypi6GAPZ'?TtCTU3@oD?b_8a2PYfO3brD>B\31`.*S*6L*N?*#dTBR"S/PG69#BIqniVUYJ^beYc*jI6&[)XU`NTUj"kUFUPIUTIAa(`s4!)-qU*g"'MHG`"/?s'(og<IC/l0Z\@@1f9st,ZO#7bK4)B&KOS0-PtL(8q_T7U8PRXB.Q0a";W&nHrsZ.i^,K[orJ)m/r?j-~>endstream
+endobj
+% 'R313': class PDFStream
+313 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3636 >>
+stream
+GauHN=]=*H&q5%Xs$MKI(@O.JV3:\">7A5X^h07[1D.eo<4Akn7RpZ\K@sVHR8l:?-P?W"LM9_UQ!%ICH'Egl'E1o*s#M:`h3&b*TS-KZ\KTH\CpH/Hn!C4brK.%m-LTO)ZAb1R3gJlmm*km#0f']T*-1fM($nO#6Si49FiZ<\PT$b7qkM,uiLib@rf+,&*i3esniL"R;k!_Rrqhh-pnR9%N(sgrXiDS=a%UikBQuos_j[m!Eb]#VkHiAaMbn$DXqf9!K,ed<^:37((PUq/YAa3$(LE6!.+lDCQ03MYI?4,&f;J4oZ!`3h</]o]?bZr)D;0fOJEKkKG0oQ*fF,l)f]<d=>W`Mr@r^h:"n@2H0*2`_nurE\rUXJi]J)pfmh6bR,i4790Qc?rF3,ARDf=KoNTZ4Qn:Y&':rGI2/m7"ooNI>8S8Zk8,`Nui2Hfo=(Y65qY!nh>\+[==lumCH48Fqj;7V]nSVncI`G:T0LrG6/jmdh[iL&@u($>%R>:'?/Wn,s-A>!-:24.Z5Oe@J_dCE\kW[O><;&9[=S';D_ZmqgDHtpkGV^AITeWjRe1t_:/-g`Yfno[OBcW!/cKa7.)AWSU]]g8ph6(&GW4QW9G&P:]Wmkj^4QlL2If"1quV.(IUU2L:jfHFnHhBn*^SgI"<A@K9"SD8,F,u;Wg[.@S/NQ!Kb!0<jBA2N/];32G4P<@lQLnE9r*/et)h\2pjOT]BheGrqf=2A[6H7Fb2+W$cbrcrNh\@)KdLi4h&+r2=mn$Ye+$Qdfl")3pl0p/V<Q)_.i8B=gI-U@eT_A?H#aaK>0?pq-tM&o3QVlHhY5u)WQl35&tp`mt]1M$ZpqT1Om4cqWa*sbaq&M0G<H-4%2cRfj1<a/]TJ[=*J'W2(I>i,[J@\!MZP'-,nKNmq\-2ct%0h!gW"@AoI239O9;Eb/B-HP>MS`^@<\Bm,XEe@g"5oTQN6[hP!5UQZp.c7dC7&!tuh5-=P/X:bk8[a6.5WVT[[G^KH)E#83ALFeU`$'5T9E^@mL6-1Y()GBlE;hoBHC2IE@o):Z-@\a"[`IYo20AOA3`O3oJ\E"C0cYg/ZkkOYJ_=T7=!>=,rC*mO'LR=+l,Ac%.>P322!n#u"$_l1M$a`3q%1%BOb[KrC:S(1OD;6G2LGp\Zq9`E@DRc245'U;=kdC^b.C3H*6Ri2P54t+XU+YSA2bWDEV(:,)U9)P@1RA>Gm_V1Ar\!BPR>s&_Q<!NN1qgE(KCFRdudFfc3\#9!:=bWqZ145jS1l[!WXc#^l^]9iiifa=6tO(M"AI,Mr"=`O4/I>(XV^$Ud/a7.9iJ^iZNb[:*ZKZQ%qYi.*IVZn[dkfM_W2*S];P!mdAZ*ZHV-/0+kAXWuc7P);#\5Rq+qk/],dFSm#8I91Wq$Xat2;hb4"W7,c236eh/c"=A7'-@%+C%FZ-&*0r@:lc=:D$B<sM'Sbj^1A4dpZ39Vp^;@]S<bC>\8/aH4e6OJfCCc/5ZLUm5]5o)+j@$G9+9F8k_C-X^6'`,oSmX0BP!KB3T*eF$n`,__CI!'VK00:@e6#X=gPnTulLrR@.+?O?GjI`Nb6pr);7:DY[nu"nS=G++.O<GB\!5*3;dLN&W51##\mQSlrsXMtFH/r\<Lm*s0h\]gfA>%8:89gOfh%n!7&otA-_.t'QFlC.JX9g`gd%J_4Ni:W7YfHKbt[50)H5%PNo^6]%rY2Om[0'7LellsMD6>l)2[=GX%k!E/3(iiP2UHR;1lVAeR[K)Al:hPHmrg6>Jk-XfWo1+W\:7D>>a^')'b%'rCP]U"k6KWEi:7t#9R?qP](:fm6+1Ha=qM]S/KR<-'ui2hUFM:D[NRXcjk'6lT'm3-afhiU5kq7S',RKQ=KRqYh?ZX5\Ht%^dYo55OYkln3@D?T]J-dj3k3&c3EDhS(!_ol2qHR#=fA:/(De1I#uH0bf;9%FM9G4hN0nWbEgRtG^)VONXegMB;:&NS_4;D7LfT@@ieN*:STU)\:FI>D!Rc7BqW>Z5Zh!iFVLpiYUGi`#K>gqA@jGN7*&\)V^ArWD%g&9'+X[N7^59L2<^;rmfX&2F&]C,2kU(.MKj6cg29%uZ)[k:c%f"jm,Qb:\_K!neb8R94Q>VYqiCV44q"fBGu$:!RpWnKhGCb2a8Cqt?OAMaj*Z:NFr[Jop9TtZe,+R_o9R80i9S.tHK[J@g1;=/i1UF[nM]Eja1,ln%cgDi+\pAX^UtLe*S@.^?(INu_e(8VVIAanL8Aoljt5Nemt.LuPOo#tX^pJ%W71R@'(X\Rs"uRsFA,@+e[R83!EZbbW?DYYQQ@En"cF7>Vhffq]V#Fmi6cps!Q6)+LP>Q*Nh)cH;*:5j>Ad1hdGOSI@(sr<o62Sfg+7b=c%$\jEpr5J3Aa"bBX_qda3.<Tin-oujgFl(mi)Un@`e5^6$6p#Orr!@(UMT:a.GkaKX"l3aY+0di&"TRAJW##Bo!\gpuI$SK0(aqN!1T->dOq1pZVo?2+9$_mIAs%L#I_L-c+/sk!'=5Bh?/4j`5WeE5)6s6G>&_e^#VU;n.Up"+S[]&WMbh:nBA[FL3;24a05OT>:a2&)[ghNQ#TBr?NT+O\n/7e'nWE3;n-u<aq`JP#9BlW<N^pGes>L\m%sVZYKU#ldZaG(<%eBi0?+5#X>e*AD@Xh-"+To?<rPm=&?'d`FAA=hOP[XNf)]-Bpe[N^=\)phcG(]h8eh2re-HT"Pa2Xg[;68*A-,go,"n]]@Vt6rn$,<pIL0'If#4R(ASE1p^T3[ph*(]?h$'Rd()79<>)6=Q4-^mrQ`^'aaVP=bm1(9p(ZW4%f+u+/BZIOgQ'6^?'F9!_X(j,/u-.C17"*Nlq?jLLI!r,7@rX'k)3ij;Qi%-&c&.P-r6re2-[-IkpP"MjQB;(l6RjZSLNG]'?sRSI(!51D=O85f0.IpKBt2U:`H*kcW9AC<81arBm?:"[RHk8`h4aD)tZOl>lkm/kHgZZq>s:O9/S:1rEKDD:nP?NfA]_/0*Sc!k^,P6H;A?4"&>ltKk\8'e(!B[9;p0r\9FY'@j".qksJcY0;\!UGG$0j50L:HZ68n1Ps/uA3pO%,U?_>XbIW!KW/!duqm"`,-02V-SElGo3o\kfDY[_Z].E:5V-jNCqlQ45%I<E\a`FfTe4r0\X@5Lc>->2LM`%,KeP](*/SiaK=Nr/X3SfgA4^2P:_cjG>HnO#R1RC2NmG.PHKM0ijKU]"tT!ZRG<jbE)lt%cilKbf7H^`Sg<HB<(FK4lFa(d'XLhRP"Sujg0BNa*U<cuqj[LptHF??s\(h$^X#N9h4N2q96().A3m,gqu/Ic8s6@J:->`1sL]bJu5O>#0A>HF1>N>T.FUXt%51gd=uC9c>9RauiFdVE4ro"'-+nf8>[F&lO(.LRZH=K@aB\h:f;pPb]R<7OW-/L6:_C:74tV<]l)LeFoPKdgN6RTdpXM5Ks;\F^[VK"S8CNI6M7])H:&Rl.)AP,58Y^8$[PD:PI--5GW?:;7%![@u2m+^:"M7m-Wkcc5%O/i5.qb(XXpcCILMmlg_g9t:r)eogp$?S*R96ah#b=!AYCWjp[<#ZRk(foXhFQnOnf#e&aJ[A*fECrgC3b88Dm`&_jQhsga6E[;/Xop1HIIeA399;X`~>endstream
+endobj
+% 'R314': class PDFStream
+314 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 4060 >>
+stream
+Gb!;(a`?/pp?jF1"3OVB,ps>M[?or0nflg;bG/1^bXE=+$$A&ddO*Y14't3s=@a"Y5[!A#[O\6Ep'&56n/Mh(jL7SX)^G^&^-]$K/7dGtl3:CoiM*AKkhXe\BA_npMkbVOZ>F+>&Xp_LKha0RB$<uiZ9<=(r#+I.<J'AQ@cjAb"Bh$V^k=pCS/WN*2!OIVNK,Re-+`pd?2[11s%`TA'-Fuig<=B"aqaPJk,U9S=XLPpQL#/n%N$m,)N2/<>cO)dTK-VBf3sTn[cM#YYOR-'&l6]B&Y34c.?GjSmF_S<B>.39Ebt(gfX*IEYkJ/-mKhZf([p2kfIMfd4muc^Xo&8#]Zmd*Nf,*m*K#ZS_SS@$L.G)d*_MU-T[Df"o`!n(UduOp.8<%scoi\?Gj&`Ii:WK6>^W,$"!:mFBgI)$qXB;do1)gCp%cS&E':Kfdphu<PQ@2J/6T@GOpBgfru6YOe)/F+q7pV!$\Z4+$#HN8j)gMn&*is$L-9T)jlPOg1bCR,?Q\J0`<Eh:17\%2qB`_0@U)T1=KL2nAo(6[h+;$;J5XkUaEZt7e#/Wl2_8`b9`6e9kG4h8EFCEO]%8ThmRPadI:=*Ar3@Bo]:c?c/u)qr@s!iGT]`*Z3/j<TP2J#T[3tUNOuE.G2#3=@T#%Tj;ZHae*gEB+V,U+i)He\Md3T3HjNn*`n96a+!F(-#0^-"u`W7l(#KE3t(iHQM/$+CE+_uW'0k%!#)BaKFZ0IH:L/#;'0K.]t)E[7c;"CGo+K7750n;S\)n;.8.hMN<-1o7`P3TE@E5NrR,Zo[oZ:[E^IdEBG:A)&3NPn*?8HG$J%GG\/)AKI]JsOG`:BnuN$/2&[C<d/YVZqa]'nIMG>#A*5$q=Y:&$ga++?c/".L=B]YY?Q86c,Oh!uePAeR6e?QGUVWD<ePF'tThAK+T%7_`Z5\D/(LQ,b1/9UJVsBUDFN!7;kRTiK+H6>agJMOMhJsP=G,XN53/SUc'II,d,LiW!HLhY![5hXN%t1.RW!Z)[3<7-Uh6/BM7cQ`"7,%Dp-)thX84Ap6`iJT[@`_^U_[0X?KcZ"I-U#!<H.,;.uc8<a\AUJEQh*1:L,:66jIU!\4lg4PnD.e>F$iLK?S8%>-:&SFmF9\=S:$q65I]?5J+%DQ&K&H3E0'K%DF,(kS1e/ZF9G%]]oB6;h0LbP75(173K68u)+iNP#pX*(A!\!Kh(W,hAo/p:2C?`qcno$]%J$jdcft9B8L@8,N(AH;u<YpM(3C.p^+Hd/^C#\=OuZ:p,X$%//L)=n.!*]LH_eqXlm+/A9&(A(qZT5lot1;6NQ.kq[ODXi@p'lN7314>2omHbK_P51V1+S(Ye&3SFp1Tt0#:!.\dl.AY#lW7d&AO4S`H12iRt$7V,>C:5>=lbad@@t#,&OsaHm#Td.GQVQ//QMb?3)5cTB(5qn*&ZI"AF*;iEY/^8(0Y^5AmghO5N#Ch!LQRYSV*PmV>k<gYZueC5hKiMZ2=A*sdr9E34l52Q.):Yq(aV-nrA)OD!aU9McQAe9U*pK1?&0*Tp7Rm+7t-"%5M`+$#*g-d&o'-%,^rmh3%@N?&jg\s"5nmK0pVi>gT2ft<K%CZ+hPY$3'Tl$Q:TfKl@Ss_bt92A.n0\;$V]Z:<7QR+oh-"r_,h?/]_%&ZC^ZF((iB15]^p4B.j^#"U@cn7+!Wub67;i`VO-*%(2if%>f*ounJF^=4=6?9X29,bjp-?eF2'D*Nsj;6\@_kQ3@5pr0R$W1Zl]ER*_,B4Po5i(A8)l8*[*.f4BaIp!j)$Ns3M+nfq"h/>kZCGg@qNVfX>dVE>@q&%i1!q>bEWJD;(ftL:^.oCoV^la7"jb-qg9IdV#s(ITO1^DmX#k[%?*W5K$_XN.pp]SrQOsn/aljN[M!U,bm58MbVN:%\qNXQ:RH'`[8h"_ru4Y`V@uQ/;47`jRX6ps7E[?M3c?&B_eNoG8":]Xgr:"4Pj<8=IPfK_J&-r[:9P+\69oZo(;k'alh:)B#/;$f_/QWY9/1jEe,su/1fP[dFZpWhNnQkQHKj<)_JdQphSTR3J;SqO"A36)0=Q;]br+2hdYSi$c@"tf$#l;nPh@,ZY?\DB6$dj5`6Ic?<,rWU*.djRk2POc3VaX+hf+XN'M`4jp3];&..qZ$4VQ(e1>A,8uj1;P]TrKA="o`9mi>!U8T$bF?>eLjc#F)k2HER6gi?,fs,qWY2Lqc=n?jF5k;nS&6dnr"d1MILX8l((ubpRlPVM!Ruh%`pf%``RS3Hj*:le3RX/9&L`4o#FXnT*_ITJd1IFiAEqH>TLJtW`+PUkR)B]&654V^qheqI&n/GBF;*^.<42S\4O(^ADr.KkLfQ"R-!,G7X,/;'t/V]l2V8]:dDm=1+cR81?Y4rO<VYj9^,b)CN;+e<!JkafDV%TgT%;TZ2S\MQkYH*t:BXN;nO,iZ5LJVbi7NFmnak_'YCedV3=rm0P^,_R9/dqPmT@nO;^m#1g>rm+.LBpChfq_Un1+j9K;&s7IaGl[ZS:5sdb%.u"g/[:rQ7L]6JY.dj!qDIpFfu4sQd2-9dXAHV$usAWO]6s'W+G$"fp53i,EnoZMAfof6^+1ZV:NOB/RrrW;2heMdc/b%C2g1qE_P5$q,U-.UTBTb3&QO2S8+U"diiAuqhSaH23J`Q-;fEE@/amI)pMlX94ol<J]4$AO`4k8CA8Wo"'mk5LGe!829%TdKk*f-lUg-423o::KksAElUg0523o::KksAUlUg0523o::KhO_mp#M+qG)K-lIZGZaO"V7m^D/G<[]C%O3:KVAOgnk05^sE6o`;g#(If[DBQ-g^VBp`8Z>P5`\44s.VU/&,!1H57EK-j;9qe%7#rI>cH(rQc428/""%/7BUK]#0&ZUr"3&PBH:5rlB/)W$sL,`j\d[bc6;lhcF,rA>6$Ji)MdhKr\,rA>6$Ji)MdhLN&IUh.I3o-HePE%[V+*G//PdA[!K%_T/@@JK`!c(unN:CLZV?X`LS<b('r#(d!5qapiKn#%GUG=^j"m2&GD2e?gNn(K]4^@^91mUo&p>us5\828pLM?Aao<')#L(i>3$u7SrUs@0";X`&tIiFnE>Ea/3O#DFfGP!'G\DanYm;!]qIUl8*R??l`T[Sg[n@i.lIU8aRG_1gJc7-mUqoNhRO,dlp@uo#8cW%u2E@uH4\O"jY2Ur09>2bHj)eF<bMn[s)s&V"H)r2N/P/U(5F62._^sTPIT2W]oX6p8!W+i\7IEj$GFH46ZCRs2A=TC*sl'f&QD0+^#Zof*6?""F:"a#9KqL)2E]SrZJPP*8dY0?,$&m@Yl?]_*qT#D6')f%/M>?@DtDm&B^7.(-SI1r_,qL4cDh]q,?*:M9L$r;1[-:T<:`no^ffG3Tsa5;&"%JD4&pphK230+F+ki,ZCCiL$BYU@+oFD]>TWqMR-_Ulh]0V]R=qX>:P&["\iofYK_NS-NS)e%9Sdd=354ebdkh+$L4b.n&laGqfbll?fm:#[s.A37*hD6l<oUDVnJ(gS4h?@9>5$':[qO5O3cO(]Wo3%WFCo1N1"4W&lgF),q#O_$'.KI0751FGorHM;\MIh0(rGItJ3F"SanojY>T`)2EjS>:J!6W5ZH&90D"G.ND5BTi#Gj;@atKZ0WnaT9KRq8?IP#g)8%/XsU2NubGJP[o"'B[W:[#A<bV?"gO,F]Kkm8lfE,b*H1*\#VR[8Q*tA.oK+AX(R7h2qC0(6)&A3T,1_IKfrH@h"r8@,mATF8\=h3ZP*;dY,:VF;2f3`#)dA`do)$5jfX9\-.UA",Ue8r4Ap,apG48Y?819NTX/"jgGl'XhIO`oCl>>BL@s^]]`6A+:Y)+uDKb+oB1kAr7KqMcIL;gFmL;'7Ghkg*oE$*$?5Vm`5!'P#*7@Y$FKBfUabD?*PcRD<\a>YtNp`W$LA]t73_IZI^88&bhL11(LfU#h9(AHcrKfQNLm%S:W<$\adX^iB6bSqbCU-:B>N@F2f@1N`_78heZY<Q8k@;FO1A?Tn#QJ[lQq/1f#ueU7s!3.OW8688fc=&\]BqZR6`(2Y<UmrAZp;s0r>u>%CQn~>endstream
+endobj
+% 'R315': class PDFStream
+315 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2874 >>
+stream
+Gb!SnD0+Gi')nJjr.c;BEc,DgI$#hbT:BuOb?Wi0[;qg5EuuM;P#.>F6]b2f^]&BWOs3?.d#N16AF):a!!8)7B6TtRd"W]mg%o=m"2(/?GHYhe*LJFop+-_dDrA[ho4K0;[p;`NH/LZJ5Jh&:TA+<r=.`Xpd']DVCn<l/<UG)WhjTKo0T3cU/KDe'Bh.&!d?[/uPqCtCG$i&O0:;]4DuZm;r_WRalb53i4get0'Csf,E9*!+PE%p%d.4*K&SZ&Ur)+l>'!Nh8aDrlB/j^`?%Ej#0CemUT(3/\8Xmp*;)_-3UYH?94S::;lLPX.t5U`"4P(h:!6G=!;%tQ1N<uaVko5)YqR.G^CGljHMra>MlVND-d/n>#$s%m["/,d"b3/uR6c@UD))3+nV$ULXPe'eO]/Mue?%O#2;J6.'0'QG&]Qm]FIRK[uQ,*ZlgQQe.>eLOdAbE=F[&Q=Q;OGfu8$9,ufE"04<=^I\"E&E/NijpYVf,WtXkUIB'#JO=0!7.<q?j0.<-tDq4b\H\Ip%J&3&BHg`P&_WPDY+7./NJ[1En"G-'d8?7"IVqb1?#HH=h%lXf4kRO8rpaQ%DI2N<gL>8_+]a5Wb,JI(!=(p<A3>!+)g&M\Ug.>*)KkI[&dhM16]edLj5d@O0kSaR/m>]n>Q1CGF[\Xr<N,%5RW</B-L6L9@A;4P>IW&U6^%Y[M5[H6V!(Q=Unsnnf7CmfD]e.*`STYhk-EqG1OtUJmREXl*tGiV6\$@;cDTJQ?>#)T9HZ'Ot`?X>/H#%;\HI'mc_IJHe\;&A0faZLga8eg[MRB/cloE"J)ou*,9gddA)R;kZMTe7g+iqe>NJ&n\`fLBilY(5oi&\E3?W!k:qQ!UD`GI_T4]>.Q9IWksDpP+O($,<ba'V!W$$KG:`KXYU$emr7+m^;[A*`N95hg."WY<Ud:,Sk#6-\pQm5b@XM6$_L_G7qO?%,^DR8NEfh'A:etb0TbJC](aql4\pU$,849/>bZ2g=4_B@h[8luY-LTTn1gQCB!tD/+as+sU!/$@U,2OFFD$u\\!J;i<8:TATmPj.23r"Tno6@?FBr'dT5o1_DH"D35=X;QZR$n;lF54d`CV`9oaoh^MfZqg:jkmFDM`#mr_!OkBdY4k/"gs,X_a856GV7@(aquZ3oII?4\&Q4#cd\t,eRSKrB=6tCcoD2[Y)A46J\5*>r)"6s%f2B1"lUi7_fn_RL`ejICMktI=RcA$PM:tlo8bCV(HHFc64BjS$H$RIF\Rl"8q1=7NVj%#[eaf9#jMn_HReLbPpBqn_]d$Q-kaV,&Vj>56,]&RY7o5DBDO8^-O321dE*c9`#V#ipjG^`3D*sU1#D+-'k@.(RPJ6S@eSKje%!`Nqhdb`iRCDU)*O["3eORoI6]UJ@3%MW[`0=si,fM0Zcr7>h:Bq*koOaBR-[8T)MMnJ2#]+$U:S^rT52o3!\A^(HC_go35pP/(QleJE)Yp_4e'9^a9u5^H%IfZ"-N>rOHQ%f"=ochH("Ji9O-Ae]:3).0WRf*1XZo(A<\P1KZk3W6UNP5&sd16<HG]:HP6i<<scL]R;Y.g>O^ZCU%4'H-[\j)o,9*UcHM0S"H=bb:'+[AMgEWYZG[pkTdYhX/Id3Xc+4"tCnIdRo)MHgC('l_M9P4?Ci7BNQKN(n^eW];PA/TLUs"^N236YH6>sVXLZ?GJ[EZAAIX:uE!>fOYaV7=NNt]Ts@W6b9E]h,,=Tirh]`^-]gF#D%?D,7JdPG_OFhgr0?,$E'>.D9F""0qp<`VYhs!R;+EcY67**qb:#[q=S`>08[OeQX?>]^mtqFR`meqN87o^L6\0h"9jek0H<(Za;+Z!3OPc`E%Mh(?+o:H`1:7uI,%,L+O9C6(H*4_BrPDtNjYOMR\DSq#._D]_TS1cUQ5*4:Sd%mRh"oho@N6or&!:!VT"3UY65:V4)%Lq9iq?3a3,EUuB8e\&0kVm5[ho8'>,bbU3OdBUI1/s=dUAWS-:lY/"3EatdP;H\Qe>Qpkq)&:[OCCsU6#J58*2ug8C0'.XdR-r:n)S2q8:fJU9ghtD!;$s4;7)%qn#2.J!215aEfgUfHA1c&VArdqT#%qC>7ja`d_kH1OE+8e!IQ0F.Ih"rW!ut]]YBdC+Q^J,Ge/5kpW.0DUSV?[@/(t=:Vdb4h*t._ug0T2(KHN5c[DI2jLddF/AcWT&PX.T.*eDtFN^$SPES,>fORX/T;d"h#WDCNQbOl?rF++)1MC9Q[8q@pk:+UCBM5*m0]4(eU7VS70S;<,#Z-K(4Q;gprLCDQpK%ZpHfkBk>`q.-d/FSX'OEMX[3r-F=^1#Dmgm;cgPt3_d2r*ps"0Val0T=PKJ8CD/!45JGmt9tBeT]DmXsA>pJ'c?>4dW@cA=)7JDh3<iWViOHKq#e#V@7Nq8ku..]D?MQ@iTQPJIYRWOZ^E^&52'`HY^+T/=pXfT$q/T;_6q*rOD3NG45M;6(b[MgP5fZr&EV9Y;240bdOas=Ni]Z]/T2#`9a'/Z"%Pr,$gAqP-FaW#0'6Q_]u;<)>2%2A5/,e]+8k[>H)Xf,Eh'HeXY%[Uq,87%JK+Pg?Q-u&4nM)WZIq,pG*?\fssC;MMf!KN:hE.@StJ\&?%hS?N\Q6Y_:&MDVi=IMR`;m+/!f0Q/$%#]VR+o,o8T>/s9%K<%USR9asn!\2b9o)>3d4jf%t1PL%+E9.rbjKZ"8F@qjA[j16,@^+lNd1?S4(NG=^(HE_C#@($FMQ-1$$h7YB6<I3[g3N`$/i'cNNkWP/6U\'koO^dPd.3O=BeCgb,*UVIaUD^W`IZdr_8\%TEK^)[<A[ru5L)$'+c@CUQJq[c9KpU!N5g\s2\7mPt)/3]9Pub:A8T_i"i;'_Z!gRWA$N~>endstream
+endobj
+% 'R316': class PDFStream
+316 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2964 >>
+stream
+Gb!;fD/\1M&cNgos'ah=<=5-+8\G>l#PV-R)=@*EB3h]0h%)#V-#H!:1:s=rh64S]?'6BXfqP#OE*u%pq6D["bWPL@XF1rDO)I7X']?09G^Jh1+2E71rm2V$r#bF;q<M+Sm&sb[4rQa!G`r`Re%4tbV-dO"-A0YU7^.=>$:jdTM'h)$4G%hc^@1#t*1pi5GU&Yt@"7eUHN*CCbWio@cZ]/WmI-t<bKksER0:D`bGds[BJkc<e-kRo3+Q307*K.C.Lj-!)69ljJ)Btcn,F"IB74/CXtNNG+=&L;^4n>O>_q1l*=qPh%G+&tBtQt0fA>;-3qHtBj4hHtLP+Q1Fp,8rGeobR-H'QRGWI9.&&8]=1/JAPM$H7!*H.A.n=<0-QA^Gf7)&!$g0j&;C#!U?EV=0`2acIAq]3?49#b%k(kb1JjBRiKEs5gS7D^51)\I'$BpS7Qj*be.DPT;9nZnBoKDXMEZ?ZdM(?Gmq+<*dB0#aj;GahA4=#o>W%Ygf"Ee,=_`&Ior<(8*N[E*Us?`u1FbHaN(DC?KZje-n)""!?%)lA<=%'1t#d/6OA@A,\6B#@#G2j:GQ.TU?^:,Vq!m0t[cN`S(;<![>b8Pn>D#`7LP9aW6!iZeq<05eT=-4uXLcaTFf)@BYU@n(SJ5o0U0$H[R05V8HJ=RZbPSXpC]p5VN"T1\+/:Q1:CXh!<KL9KuP/!:$W+Xnm\fOWSsLdoju2]@1>>IJo6*-bm.-G*C^Wr\D];T**1aI(7A<$Y0+9cRT[.>`:1G??YI0N&f@Nn7ba=(GK-7;,44?d^(/#0qX4J4&X)$c7t>hTbe4=P\$SdAT#BXt8"1J\`O@bG"@\ruGP`(%l5]d'f`uZ$_k/TjZ=d05*M"m)L1&)L3KdjMGrB2m^Y?FI(G%FF#UF64B^5+]HC";he(2a1LbW0cllsX0W+B7^fK0rnrdm]g%q;Q-lm4]9RH6N]E9rRrG1)-t.k3[hM`MBYEks3D58Rb)9P:U\d!Hs"nQ_-Y"UC\d7#DU<KJuDX_7^/4[P0&::Za>&V0h5pR4nbr1.jhnlX3dTfIC,1WO4/=RQC'#cW$>[ghkZUX`%,8SS;n6>QL$N64PCDE1,Bo]_qJh58s2Cp:,%L6OA<9.mTCstt"`.G6Qpf;h06,^j<%OfUL:`J"DN(m]:;D%os7;,OJI^<!u"RSF'RTjL5"o^OAR=g_84%Y<:"1"]6_s-*I9";"]B:e!Po0U17:erFJ@n+1#*lPi^W-V<5Q;3)P2@$OLFQe`?14bSZKP,'HGJo7)!0r6`74OS8Urub)G"TYkQT*@0jMsYk-hR[23pu>egP3W11GO!trUTpQ<t`Ahi_=$0II%D5;urg,U)rr^q^W!.4VRSaV\DbfKe/+[=<LbMH)>[i?YM!b7SSG:Ko-B7I3Y,eM+-atF]coE>OhW/B6'SM<PnRC/.CrnpM\3pl_X;G9N?m-LI$@QL+2#on(hD@+BPIqW.M(O:6(XYS5Suu2ct"[?C#oH/GdFgr'r+(;]cNag!,0Lg,fde_XeR]<2$FP"dAeS_tnl=*QOe`@e\9EGq^.sVpj[f)kag-2=oI9QH[Vfg(gs__0]UrK^GjUrEcgH/L&YhWStc[]@?F9*XkAR0Ym!<qYIufGqeg&E7DC.^&1M2R]7bA]Pq6)@$OE6!l7M]cAGkh)^?G%JJWeYMJ,u%5aa3J<V<OSJDdEDE=nL[>.Bs!KW=(&I]J?:H*[^T\Y`A+;lR:gQo/SA>>]GmQ]MtY#G6:k(T3&&Lh8;5<?(7(9a]/!Whr>@B<<`^Y1UlOG^8(X%CF:LmN`[1#%nlC:MIiQa#5:u7mFbH2"_$dCSB=-S`jL2G=R-Xg[H@A^A8?SBF88$Dm^=t'UO[&4FpVmPI;jjhm`JT#NImV546!E99gc;91=(]I<MeO_njP9Sh\]P'j)2k<DA/1,ad/(A:Y>t!.$\+7+lm!X9OLb>M2@"Lu3JjLk==TXG=GjLgop!jHh*Ir4rBm9QWd5)OufM(Q/>`$8WQ?(g)6ciM`3&R$,;tmX)iqiVa_=MnV-<bj^KSIQ&db7jj\DZa4rK7Dfh+WZgQQ>,jumG!o6:bA;jR/PVX/"m%2V<8EtN"jQRCPR:4-(XMO#O+K#/mBVH0R)dW/EGp<YeRf1Xc#f;r%?e3/&A#3+KY+t*<2`)l;)K.qru6$]jI![kdlZ/60;VC6P*_W6I&ln[_ZjXUhU$(-NXT#m1dZbEPAlLn6n&D=Lt7g^bInH7_P2iMEd'?>0o*C%_2T,].JodFE/GrNVC];R/2$(I0Wn(;8j(]^`Xp(Gc.H@)P>OtR,WY3uF:595r:ho??bZtPLGn1=?ghic=^+fR!^a&7F*?=AW]Ebl[:sK\X]rAZ^-,n9b9^+si0mgYlIK)QbW/<f4Ou#d'dBN=%4f(p7s^Q/m`OQ$/ET#!Qp2&[hbo4,Z&f%]DFpO<<]o=:[eK+AP>7u;6'qB,i7ld.(Ukb,a$nP)M!9.bg7t!,VGrC#h^VH*V@<8M#)o@1.ciuc,Y=+*Bhp.UDC>H4Dj<'V"CDH_:J9mJcGN]dpbAk^[Q6$;`EZfF:-"L@g-r*i$aK!%csC*@02\')]"kA&QqL[d[TQ'XV'e&ics>o"$OQ6FMW]Xp@DfLL<%o2rGl&9ur+>h,3-2G#R@m]>WT]GWNq11t`2`KDoWE%./Wm/P=t,N61m-6#%-`OC$^?unaK(%^X(0-5[F3;5L"PU;EE$5I3*Wr.&G*R1Qj;5VaKbp$Vj#F^-0"7.l/;.IE@cNIX,;Rf@\@LTCFeCCn/%u/D5sh\gR)M)802)"doo7cVuBgtI`:11@m*.NL%Z4n6u"B&0Z4TAcUgRTmSo9OZ)=Q!dg)\.-@#>N%k4A^5u$=dIPoo9s3bk'PG0;H5-6!&9O5&lWBIo!=p$WV7a,Q>6YgR=;RlNQ`T%K+K<,TIJ3GD3%=4E.]2$C4ldOtq]l\V>eF<=b+2ZsI*<~>endstream
+endobj
+% 'R317': class PDFStream
+317 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2526 >>
+stream
+Gb!;eD/\/e&H6"/s5C18F#Sl^AGIP+0Ha$:Zrke[[>/0mL4PY(S#ms9'P5nnot-u*/B;[LQPLMQ,W6s2a60&+H]E->K0PCplULq>NT'+X#94Q";fFk]_>#<]NupU_@"4a,p7;Mlb6C+WAn0VI1T)4&K21$<Ha%nq#\S:[Ka)AGn%gsba'j31kGK%"X@Gp,m#R`(bNV0@nN.S;A!_[TIm9/>hV>SPi-Io;.;.LM:!JL:Ygu^@3F'LR<\aZAFW&uBSu\\i#i14l9+n'19U3WDrZ$;#:ZX.Vgdi0X+B-A@5\Q8L6DR)rlo=JoJ0a2q/->\sLM:?U/H@.mkls!sQXk;9%Y/L/JWBJ$hJfs;0jo6o_3I^AoG--gUSXS@2Qf:2dd56Fb:gTCH2K&pYCd%&HdHD3Dhnm`_!CZ]6QaLF&4W;3YUcu?^&T#sTnl*Q$Fejj3Z<Vdf!W6?>5/:;4Np3^].4:5-t%jO(a'Ag8a_ft=@f#Il^#`%Gi?fhaH./3e`!Qseq--Q:qdGqnZ>>^VL=T8_*,!)jlZTbR`"$,fn79/*d1q->R<XU)K?Vi>)4"bH%7_1dlD?lP2.3=XRC=7[g<X!OsH9@iI7'=J+W:=h&4SDJE:$FGc1A?;Y`7L_9BluaoDgkBjf]k5M2*!EF4$X:Q[`Qp#EL\\Ns[u10bHk6o,U8i0ME(ME-?<N'`oS:_;9th@eSo:)4Z<`N@?a9\caeoP7"f??Faf)N/RpD<,g^Z`%_>'masKMS15D3O'U>a[sePRZT;8qRNmZ:juH5e"!DNoAO=pWlI_`^=KSHZ+5Qpdl_sq=ZqQ5SH`W<<)J5_:I9Vm+:8gs0&7AG@NJ)_e9Z$e=`(YiMunQq%8.?tU:E+*4*ipt;P,>5\*HsH(sfb/P1I&_cW>iL9<78oBosa,/*V@s[BEM&VB7L=R\JN`?#kf<mTO1/:;6KD;A%@L#7[kTRbJrj'2hML(7K7M\qh<rYmr8d'*64&Q(lA7pKH[@6*!IAd$A4V$`U7."R&p\0Lk8_qC(CW=823\WQSRKQ:<>8D9,Vf+&n3bnB*`%V^VKZ^'0iH[k>r6`X)[!dd:RkD@dDDYg\8]=*=3Ooob9kW0u6"CW7J7r!Y7!VXCHB-<LkDVuhV\a+Gk:QIQYFQ,22mP)N\tAJV>m;rLkC[ZFs$(0rg3VAAZFXh,rt@ZRgB](kAUg)O\mghC)o4uH./(j)t>7e:.c,3-Q70`pu]fuio@?bW*Q&lrS4HC]le#$Zut336W58eGD2"]rC;T^9t;"4,=u5s9N]m_:-.GRYRYEucf/L9tadQ)^gWZ$SB+]PSKPRQ]&5+bR0C=cs[TGZ5PK:RmEG/q[N<HA?%gS%(r6?iTunWn_`.c[&HTF\\U#e,MbNrF/7u<ftW)#*nH7`kFro@Cm_Fe&oXcV2Fa[9Vq-^@dN0oX4L>Q5op`$A!YmP(Q=4Y6HQf5/+S,;'1#OKGeBRH]>gdnc[/06rFe]H:-_nEm_-uYEs;_^(E'X8LUl:\[Q)4_LrXmtFJ]nlp=4>d#kMBIHLp]RjE)eSN_k\S1J3nd8ekR&\I.brCjE6;-T?QoNq]2fUmKt+km%@h&GAh.LsV-DL^O6M:G9K][Y1DpKNS[4Q.B_7W\[Tf\VEL3+b0EtE%Z'3WnQb>f7#%=,:D)%0Cde*BDgN>;tJ0*[9i#PSciK8VkXiD37pkJpF;1-9'g5r[gS9j"UJ%r"V464.18EsYgbMbCit&-@?["o3u#KoJ.tr;#tT79c&^-kYUmOefN6e_e4Zj$r@l-TDBj,hG71gU31'*7Hm7;K(PR2fljIKdph8!]I-as3\(S)>S35dXV052$CN3Yh"-mQ+8dZTQ&94B8=ZPs-,"k^oMQ\OdqA+&QeK_"@=)1J'Rom4BIGSTq>86^HRaA\PG$Mp8:aO][rE6X-qCNZUF^f(16?gdhrPN1U"]<V3%u8mh!`Qr2+K&J:d32bg@g`?U.Tr+SM`AgPfm,G6Z0*n*iFMYbPFiadb!R(@0Q@k&:s5Lm`1DsDd`CG;02(\P/oG9NX'/T8lh`3kb%h?JVR.sDWKa-94R&f_m5h?GE(BCZRh3N1_9ZRJ;(/H6>DE&86EPb%\)#[qQZUM\Gg+&)LW6Q7.oQ.3#,ehi8):;tIl@$adl\79V;J'GaNl[tc`/9;-`I2=\2Gi]WX)UV'pfQ2O0+Jr1"CD/P;1M]ljP-Q%&h(D;Wdk.0rRY0H(dN<K669g4ZQ_jp/,n?om=_-s.>S9el,#u',%"sW#\hg/9F]TG$ieT[Bu=[G_kI7'%1eQm!/cDI;\F,8h4"A@roLK,Nj<'rU8a&*GJ)m*X"57-jRS)??r(/d$D*>4YYE#8;0WV$ln`3@/J_>11)DY/a.@?k..n/Jg;'8"*acL_,!V&e41MZ108SIA6AAY+qO8o`H-$T>7/,3CtdJe-2>)Y&FMdBgi-QJpP%GKrV)$=T(C3Ff5J^Eg]#T?cZ"G6Z:9fj>8PVt%pAc'L_<[OY>fm]'V/gJieugHHLl@Bm]l!Tiq`d!5PbUUKY/E~>endstream
+endobj
+% 'R318': class PDFStream
+318 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2852 >>
+stream
+Gb!;fgQL;L&q+ths.Lr=P:[4p;AVrp-YI;"?*SGij^DpPWIdZ3_O;``!0k]TrH88g7?&W=C-30ajkE<OJOZ9\h5?_P@#2Q!pNN,.I(t2EY6"tr=KEV^ZS=#f_TTpI-Qh.4TY>h0L+m/c"J7^L5(LhLq2Rn];%QK1p[ecp)RLGPCc7j",(h"GGT#,2*@!J9/Vib\?Gf2cr>$1KK>g(1p:n,p+.=:#\S4bPN_c$`]+(=5k@@2ss'K*B\.57SR7;AUIRnsoSd0]<r'-i0Bn8XSnk6%+GQTt`au-Y+je)tTch3"JE!t)&+QHJnK[i26^Z9)iJE4#oaT.Q[h+!4mqV++0GJe]>i90d(?i/H)5CJ^4.%ISV%T>9WbRi227aZkmA%])B.YXp!E;+9P$dbVEg4J,dLm?O8[]nk-.:@ktEs=gT2/8_ri-D&^9N\B:.rrh?0^N-r?cdGi*CaiU=8d*MnHJjBIH<%,"+CtSPr]ZdjCm1Po>^ac)mec[lA\n"B0l%6OPRnRrJ!J>.(%^N6m.o*i'ugURGs"O$D!q^[fT/H1e;`%?L_,_-K5K\V9']Z"JHDV,"P"O8:a=-Q2)?J$EX#9#Dd>"i(CBC:>-/iac"Ta4.c&Oa:M-lRBL1^Qo<7)=Q#ob@4W=]_/kZ$r)ALMo#a7R9;96XO4,ir"te_:Yd_oBd^lcHR<SqNGp9[0Ym2)h.0f8.5qg@"]g]X!E-u(T,m58;:PZt-7P&'p#!_NmIkN;#hf)i6G9&^>j1tc9!Lrdk+eej<ARYZ.6s_naI8@Y[b1pE_!,DVP)!$S8.9P\6fC5Me>/<'lj>pf?_SHX9.oODBmMBnschMiQ.j--!>AUiDM(U@dlYRX=OXlgZ_9._bL)+R-P8#SmP4PD=AaBj[\<11'\?YhZl^rWQqZ<'(K1#cFacVSi4c>quV6tQOHaj,,8r'mbG*RfVbG^]^TjJ#.(<2Z/m.)\[GV63?#og2OXU9*&GLK\EJ,UaJpPr="kSQ\'\B#r!kK8B[RM],$1?Lr1kW3b*)6K58:7XpSUqCFo7'h.<d$`+18!G_eM'-mJ#>``!qs:eI_?d<lOVgU/7&&iNS:cTZR>K7<pkQ`4jd]eTE_KJ(S21f",T8jq^)/*<Lash'6Ia,[^P1_Dh.l&&&bD^nci3WlZ`dDe;L!*SQKW#V!;/R&0_rpZnl%rd41N(*K*aL!"coLD*uIS:h5#$4mc0T&h$N66V-6r+LDW/dM<H)!41r?=k;*h)qer"=IP?3%dFqo:A'I&A@Xk,T7OqM7U1*;,MVf*t:Zt__Ao1O-bFG.T6nDCpmZc^ZZGLoTpNR_1T*%s_[3gU=>+)[833LC\XY=<6!qgMa=Q(XZKjs!jPcNJnJFoH"3j)f)5ZXa_@WH=(^Q01lYDjbb]t8:gCcE;.B="AU&.Gi(N4^g@N'a2??F=DUlPHSW/!1cnNo@n7.HA_&[\Fubo`;6.WMn5=rQ=`(hfsiOlS"1uNj5R[YSG--EMmk$@2];YNjS.Vj?do36T`-RU=MPh,iGOs.#H\R]$P/dC8K?Xm@9OpQcAbq\DNd@'19J>moq?melKe%b&u<"ha_NCh/O:`Gf[H^PaY&d)UF/=MGt=NU&,tHEO+.ZQbD*gIOA;62a`d</XL]7J#9Xl\9dZI,UtG$eJPqc,K*)IlO7[gnI0ClMWTqk?coTb*/n"H*S-1I!Ll4<YQe6&76i!E3jkbKX@42BqTP<!Nt$;qGf%c2:0*f-@m=JsibRL#!rBFT`$mW9bW?/,(u9P#1Vs@p6u)L+91*"BZ2LHF9+)H0W0SD?539DB`kt,+kH1u`N*8Taf#%8:hVq/Z(\K?N!#00lN6EOnKM:$X9)>IGd5Y[Q)*\)+#A?chP\W?DX*ee\;c$64f'1UorTfAA2]XKN)Et'PFQoN6KtX=U/;HBs<eZhBl#),"][Lu_<GP$(=;"G6X:_?kF=;8E!N8+gBM_W'4fHQqhNIT4?aZHA[^j"Y$dDu@GouAG4#^+uA$Fe.q=nD9YgK5[_P"`.$O+7D#`pn")(NPqi5#j\']8^I<*'JH_[r1JSQ'CPDIL?bd+M(_(-\5oNVE#WWNW.@UXK-YIMg=)7DRphOt2fS"+fDr2H>cm`VMd6=QZ371bX_@X":5FCHNVp#d#jQ\E/'CJIJD)#Hj@A)B3f9O"'u&ih`QaBr$E'.QZppgA>Le0!A@^>V<OQ8?'u/Gg5&s%/d1%?EKL)U1(6]r-8N!l)OoUO:tfF.&E&L09M,dAME&jp-ei[*fWr%KuX4=d31*@:7$-#kA-?IZ#DA,r+dmIH/JB746$2J1]Zl#1>WSo$!/LcI#9[#H)fUS03)`7C&eO```7=[SJe<=2P^&:nb[HQZ@CJ2[_$QA>!j;R<?bqfSuKim&o:l73Jae61IA2R6C(ArU^-2kk'PrB*ba3V+6$[U7L\0m<eot#_/g\#(qH1WJ'tu;5'l;fH6NX\i8QH%j<(446J3I@7\=\)"<uDg(q2_j/["IogOgpP\j[Z;QH&@6hF+0,N);uZd9e.$?o!DeIo6V[,F-TLaCKaW,(K3bkD4i.NE=Gil%=.8<;n=B26Sj*Cf/f?==K4JLa8=d:aTbfh6^Faa5(>Zl&60t:;_[Qc,gh9.Mtt-P0.,UF(q"7jMd:7lGAdSZE;Rg.kS\sP]Bp:6/[cd_-3T8ZP>MZ>[saOV+'fM^>7^'Q\ipW^nKU[@4Pffc63'6r9Q$5VnX@A>qVuHmiPie(KZTkqE"bjS?Ft&eo+0>7ErnrieiRG+Lu6-TpI)n2T0_.bkr(0b<&31kHct_h0gf'aP\(GkJEfnps3\,reA"VFUisg/X^#Gs+D4V;SK16DD1qD"]!TrGl$M$,?#1$~>endstream
+endobj
+% 'R319': class PDFStream
+319 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2269 >>
+stream
+Gb!;egN)%,&:MkuraEiC:<#akM%lf[.8>-19Un)M17_1r#De%$,UC/*TH3.[]*hq=>II-cDGlNYYsT+]h6Ub?0&Q_!p_ERRP60[?"[)Z.J7&eD'a,Zf@IY7b?9E]/aaXQ?lVRrJ0oI8]F6RrMLI(fr`M6!YNo9j*,IAA2)oZVONF5UK&2=#!mF.(MMeL:rs"\BB&)nt@p]-5MIf"?gqc!C8];sf,j7$F2\_`+ueoPl.g],8(p.p=NG)cF250,djJUnlU5?Yd"!+4jiS;(#(nk9l3B0nTdgd*WGhnFV!YVq(p@<MWl"Vohgqgq`#rr(HhNtb:-0cL?OARRF5>SSrL,8O#D`V*.=-XV^?U5Lea^q"P)\4j\ZPo;5QYX2Iq0[\UM;B^j(2qEfe\4+1RQaoXQW_7-!+2>+#\o3:Q^O0k*;mb0F_Wo8h_B-K<kWZ'Gq"s[i)k<VdHq#hRADSZGo[MDAYT2&WC(2-k=)7hP,t3jh4!W8/A]X%6I&\Rq8G,@ad0]EPcimc,iFGii(lmP@!Q18o1BFi"V8P\jXE]n-L*mq?og0TP*/$:rd.6@>i5cP6;JoA`aYV&0e-_FX<=aAl'o[,1l$++l(\SYh6"p/%.(HHM2VnotAeY)o?]S!;3ucBK3cpR(_41\F!;'VBd"qaZFXmgc2]d&K-bm?Cs8"#K@ZjeAAHogQ,8*;5M8:^<WmB)D;Fn4"2lo(@l)n3u\e)*oVEk!enEfU`CF-!%9$?tEM'Q$j;ro=#O@g;ZMt!$RSU<Q<9q<iRE6XCA<HIUPiur#^A$esP3P:<Gl#aFJh^\<b2@Sr+OpM>klrD?9R:]dcldj3RT0R7u1\'Vpi`\-40<S8,/G=]Km?9p:=]uG(OUHf[TVA=h\^dgUF=6mQQY_.5@bhR41D!%5H"+A*G$G;j.ms8;)qfdAVp.P.;E\Hu:QHg1lVqn9T37:iQ"$UfC`S+W!5'kBr[\GA?lZ8"K@+@ckbBK"M%UJ$Y;gqc*9,*8ToV=J7eOC=lHsLos*nO!?ZSmK_U\tN\'XJt_,%]UT#!%7EP,L1^@E7kK1m@Ms0F)UbLZ&UUPgEu4E,#-1oRaGkpuE\%IL7R:.)p4qOiVkSHU(jZ+RtnnrOe`4eT8S2e5l3/[5I6'$?sqXJ7-$:Ofp=%QSV9E4/!Bf6aA6$9r.,aFl![=o+>,5.L4i$uV7@Rs_%V/1YrCo]7^BCF-iS!rFp#K9bEdB]"ed4k"kspO&r1&)kk.rJe$Ad%b3*(WYuaSnjXR_sK4^Y]l2fraLVR^X7.E5dQ<jE&;B#8[lO@;VKEm<"MF-gV2,SZ\cHK@CI(U-IM1L;"-Hnm^<OobeA;e.6F`:p7>Nl1Nu-eiB[Y;J)BR)Lps!lV;&eBpMmEij68-Pl#msV#&O,NLUSe5klP[aE/TAGe[="qp;L7Lj#^>8QQJWTg>]FY&,E3CP4UhU><bjO%&$4;S!1j'K2$'h*P"AM?pX[mm)XLdM1m5,ep$EfWsA#=V89$>2P"b!D'1^L$uP6!caN#E&emWc`g7W_%=d1C@W-MFMT"CD?O0m)84M6T*d1^X@gF-0Xd+>Pac*CR=m\*sfM4@\I[p][.7DY!Ta*EZ?T52"^J#O*Bl:Mo=p$[?_WbmFI8_k0nN<u-5%X?kJ>QcpmU*-MOMOTX35!U1&X1KoZGCD_o6Q%-F1(R.\8uLN6IKoi;kGrSD7TKMa_6o([UD2T4$8:`n?(!.U7.[mi(.g0T#k4W2#0=WqQS4,g#,S5V(#;GY*E86KHnafG[B9r25Y[/ZG*=.5*]]>YBp:YE0INUPqQCu^*sSZJhoA(@Y#>E9_N&dX3:AtS4l42A\ijIr?2PFF$qXZ^kWS:5/2eaGPq,35gsZhfCldXp.4gPU=*)FXq!TYh**Wo:+FC$k%uCQAu`e#Sk,(.)raN19mTR91a;+BlBXG+BY$FW6kF[P2Mg@UddrZtmXff#5aHK&A3,pEDLkTD86K934F.L;XpkSb&>R?CeCVFZK%Dc25Ep>e<@(F)$?p/\6'G!<^/JiqdB%HgkG,=<,rU='fhg1h5KHhT;doShLsmNYgp@(pjD?sT$'RJRp.>?%=-b&tH<M-./(LRZr\n[t=mO,"lOq_CZ`96C%A(&Oi:H!8Z'C9KJ0WE*qT,M-5F<^e/8S=g%g/)IE2<-6<j_C"He-ur?_=p4&K+G\;]#ESD`"F>#eLAFeLn.&W7l!3fZMkJ)Hl)5J)cHcT4amimO=:J?kImNkPeYq!S'\2RHZ*(bKqk9J]EiN!E]SENr~>endstream
+endobj
+% 'R320': class PDFStream
+320 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2691 >>
+stream
+Gb!;e>BAQ-&q8/#rkgqR*LR\BX4o#@P*/N!fX6sPB9(;[+;0jaO9@q$[e9+$$h,K9ZKX>_Hc@+r,)O9JpY0U>EhSIWY5.BR!,q"=3d&:3@(lcQlZ?S7!@IEiYJ-B22h/Nm"j_5o4^>=9hh;`Q\E=:S*S9Vnh<S,jeL`]u35^1Ujq5,+K9&knm5T'2Zt8"iUanEFLW;+K'BVNHm=-k*?]'bK*bmKEHR,\\3r:S>PjGcJ:(o3LEKEd)JEM%4@e:aEE6&_(5fOB)>N'W,HHe8L&n7h+`."'W*&J1OZBk"begq9u=NVYOdsFEhTIs.kn7@h</J]Lb4/(9\EcIof9Z";[$BlLDPBZqjV_&HQ@/1EH;%iGU`u;pZJeFmo)SM\IJ5"pLHnhY._rVdh50`6?;HRO>#V&I[RGnHVU=UAS=7>`re4F_2*Qq9^2@b\jcD=_!)DnkH6PX9)UBYV:J14`P,*V<aHN:C3QN#6R^);+->uV6&Y2_P3IPR>,&<Z4gE-(Z@R#7BnjuR\3)XDW=?2"c:IO9sH@R\-"h;tOFj3gMA!$Lh<3fug+iTEa_>ZSmOS?>W?C"rcmIHT`0hDYOI$(:Wb<p2_H&gVjmVHbE&%RdrZUBiUF$t+=tDocYuOO8(+9pfoPV-Z+3X>fKo%34_]f5G$2MS\V):;;e_h#Y5E`,eE+S[G#p?L:c!Z^8#X\.OHtAHpL1Mj;TlE`PIE43J#;G[e@?#*0WV-K:afde381o&AY>_2+bbV8QZ\+TYYn.MheM`!/uCn^"_7T2k[aY7Y?*6-$Y#8nKMmE=4g6q95;cIg;$3=J<ZNMM-2s@U1Hel'A,c.72`RAcA.J*-pQp9G,$GTB!]02j<-9@*p3bi9NraR-#\LgH]Nq!57ebP=Of7lZo)c6n%[3k$2VfAHEC+3uh0B\h;$S0?Mc.9AtLsG\TBp`+.4m*rFOKgV.j(b`)r5o@d,:[]FQPVVNYYKqE]$9rk*D6d5&rNq5$>)`$te9GqYTe'\G!R*l89`<K.j2BN[0=WA)0TpgqK?A55&nE@.:?SY#:Le2eT"dbYqI'ZX@8=3<;_!<O\nO\fdro8<(O:>'.T*JNA[imq-&roY2d1_u'FYZg5CscI.oUi*em<W-P)AU>=ecQTPe3\YM?sAoY&PF$pXLNHDO!pb!$,aU8mr+Y^c/=oV;T+#F>efT4MQRq'L7ee08<C-Gm'ma33u`<bTJRiAmsGhg@FbZV:3)-O@(jhV0l2st']oHL-'c?*sEl#_6uGIfr,k5)70VlSg;a`993XG<9kg]V$-9j'g1a"6%+AM"uWI9:Ne.Hm(sN6GKqs3k\[OEXYTo4>#N5u&%Q=3U]g<r@QgpbtWmC:6DXM5F>+bu%e4f$la4M!MGWWnRK82!#/fVQ&_7mWP5D%/V:K)gZkO@1?F4j"DZjT-^?_^sGb8`>d4pa73\t-<(=(Y,o+p'W"oDRf?^n^XFsCBs,(@fa>u<b(caK/_?2M.AWgrc(a?r=u5O5ZaTbJR]kUi]`)<>k3HE"oY#0Jni^"(f/pW^hC4?XO-ao%i.j^FNMEMXo(S'Ca/Zl0E3^V>e""ol/388eF]Nm,H<AC>;Y.P\``609FNRan[G5Y\'i7^_2:V_0^F]/Kh$TQ.LL4]HDI2j]D,Tg_E$8[&AJ+&ZI4*LiE)+5_9"jAeFp<GGAU5K4>8K6cL'+:j`:i7_3Y'@HmY`BgnF1D5[s*lG0=2Oi,ifAL4PJ<OTeta>"/a@d?G$1-6Kh@eIF;qcJC;qZ:$rm9BG<"12PMV('e5oC)[i\\Mc5aA1`$Kn`c!4VGW35Q[:&RkanW/Al=Tqc(#DFlVg*+6Ubm:;q]@HImSIc#b`_WgOcsOoX%[n^<&A1*0lN)OLS2H%2Cr>%`]=9[.-A8&_S#Rueb_Q&YfaeIB;lW^[<I3`7BH9n4C,@L%jk#qc0Yt49'n:%jc8qp,u$o\=u7CS=GtEI.9=Sf.4fY#o^If\oX^([pd&/_h<Xci_d1'bS\a!pSu(mP>0Qdn5M7ri+eP=3#eSCE/W"i*1La]X@#*Oa`U`^+B]!Mp;X--*bU9ptk+$^',QF$I@1J=jp1k.sp+/+]F`AEoh_[8I/s/m0UI;nUp-#<@M.**2[adVc<"cL]:R7N(mCP*mW+a**.4,t>F.4IKpIK'c-pHh=<ZpV](tFo"Hd;1i*:QdO,?s-_IB#)G5j?]*fEkaT\)/!8Bb+^[^,"/o4KOATDK-%U;6`MqMN*e_O(q-6,(XkM9n:*T/SlIdm\';RfY"]s^`=E)2D)#<Ymm>f3aucH^?bMf?QU64@l*LmG-sQ7T$qVi*NIloO'=:h9s"Sa%'sDL=4T&H(>LF+LjL1,K2oVY;n2VSg*DH>YmM:H6<"U?Q>(WMP^\@WJaor);EqZu!Nd8CkM0P/J1268B!@NX3bgulSK:C[chKuPD%E5tM1;Y0.<?@o0+hPWDF$,GA:-C+6h,Ni'E^1&^_=C.=>"=9L@ng1OiCE?HHurHml_H`qB=I6Xq-q()knRIS`^<bi\pD@Ab.Q\6AW<De^lH6VI,<o2%;jVi7mM`X[M>%72"^+kEm)&fWsNI<9F&Qn;L6c[dGQ'a2fGTJLu7aP;+S08ur0>SgdPhVYr&(27&]!eF67SpcX$@)O%E(\gXKt@$0=l[ba*[Rsl4!hYhG63M-.'qD>tBSKGrF&^\>Z=+:6\B^E\~>endstream
+endobj
+% 'R321': class PDFStream
+321 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 3044 >>
+stream
+Gb!;fCN&":')`jos'_!BFY;7VX*qVYj>_:#ELSqi[fqZ##e1N!b>o5jP-VFmoll.d?Mh%ZZ&;i=0^P&m%VO(W3AY[]IJaH>cR8sA1P^HeL(Fi&^4^G>N*uVeHoliRifj<NrU&VW$jOOiN6ejp&)f>r57=@e@5o+ArQ?"eC05=0%;(eYbYneb!&*C/[,Wt[e!>FZV/G6;4F7P/5@FID]D[faqc!=6O.4]o_dUpBRb`]YCVmD#$ob:-DHh>\_titT5/+XTqsDG)pL#RiSDo2>UVrl\>_?8_.rV@%3k8WI="O-^'`MROdbAQY`?.2t!PFbRK39p]5D4b^B%eX[1'=f"oeU<4ja"-9,Ol6R0u"A6s%:2'&;`C^)<eId4GClE=aKao*YK&@6=rBnf7;)f7>-OoF/I/")E2@Y[)d.ZT1._Yr;M9oaaus2DOi.7&C5d@gq#=&HV2p"[KDF0"G6\,Q-@J:-&_!*(G3ZjB`;O'GfIC@CVpN(bnH]>bkTi'49$$`(*uDn&T:<XrmI5'iZ>o0KZ&,ej5lJNpS0k_k3MHU+'\UQG[U9N)lGiodoT&rHf=$4S5-1lACR<[mc`DL5@;`F`U:g$MJJUoeiT,5"qo4gJR?,QLRSsHN^EJJ1?s?1c2*N[cTKT6YIf-1*$6N/QBR(%@//ehl:?d)hAr-\rb@HMYm5lrZtH<`.hVqWWU/Lp^Yo%-pArK2cdING\pt'?o.3p?`%VIO(aKPOkE/l(#]u3l;RuIhgK%;:f"jdX(@TNK9VBg],hSs'/JPZ@d,)]tpoQNEf'-ReVqOffI`F1hQC(9h]ZN!Ub4;]B#gl[oG^%/toEYEKS8/\f&j;26f9g!XLfWS;<Z$+nPYm"Z>:*%Id$#d`DI*FW@j5?>KMuiu4g+$`UpLC80olW*f2tcsSVc@Dm_0^fcMj5l[:CVLp^?VL7<skf=siG8oWAIE!3&de.eFu0:(t9=LkX+f[RQ$(YkVj1s2fE-kGYTS4n@u<-AfCeh$_,F1?qPYRqh;8BWnZab1SrCDhi,5P1EdI<D-2aZ.oBo$cdi4,aH<+cDemFC'3?B4rDrYh$I],*^r3M8m5p7aD*0IMWtDXK#mN"gq:'X\\W?K]-o[3>AtZtgjT>7$1</\[rc+Z.#"S8I78F[,I1l7HU+5E-nrs\A[g8ehn=E"_-f51_C:.:]KS\E;]*_*_0A4Q.mH\bqB/DA(.=4Hd[^grD9Eaq9RdF[6h./6RK2>iIT7&05#N(f$sAMhiPe<iN(m671KQ)Z'iXWc;`sOn?$#Vg/U:>dpZBC%Q_n#Chs<l$giT'Y:_4?ki^h#*@<Kg8oli["Y%6<;gRV_S@<WBF%J5pNhB`_=D#!Q,BHA>-2OO2`khMo3,F`'!Z.6P7gpq[5Dcn9HDd)sAWfl*'^ci/)(rpK!)P)SQMrW^9jp.@NI?i6+d!AH_lk]Q?%!;S!82<e2M8[&]=1Qh84TDELH0"j.bipZJd`1nj:;gkZJXAMd](Q2F,;\+EY4Mp#'HCU^.C$M!<*au&HV9PP;lk;b1.8JnP^O8,i_IQ],MBH%#/Lm7b@is(cL(Xe@YiN^,KrfC@4GZe-I!E<(^*a:$OP[0-Xn]VCigU$%3hu\:6.du9nb=iY*?steCmHI$U2SLgXjHoB-)F/K17KuD`G2B6E9In%jqm0+jW"BT\rim]%C2+9%%M6:SFh4dj<tP/N=Rt4=^">G]=nOb-uT';r#c"FB?)Lrof`8m#/s4G;IQ1NANH6[\QQNc)e5'Vi%fNC=KRa;B<Jm\<I?N/iFhT.:/JQYDX[kgNlE$\bHCJ[('+f?S<02lJlR)s*4LY#-d/g9AR.APf*As[X/#p:1f"-Y\*B$.%asJZQ3&bDhYW@BY(E$U?r7?ei@SLL1-ifYnaG^1ae-\G;:]/:08X0l%L>:qoDj$/n;AtZ)'(Q).'4eCg;C2?*"M8m<?X>f!`94..>llcj#ei,5">baZo_&QU(m>Me#MlmC&el4K#J6FNZ@V:dNiH<ha%8of@1eA`#KSQ7NcZT%5\K]1ja%)?Z_S+E.-Ts+jNsZNhCDqn[N/W\,-J>n8b!B>GJA=ada3"!*$54uRsfcK>A^k)8@]cq]PZ18)nFi:Yk)U<&1K=u%+5AO`/k%.Ot-",8\lg:k<fX:ftc6b?6cQ%SZ8#1V#SGnhb0BlRe+!?r+FE#eqA=-YeZC05$d^P&nm?GQERaV*@rOT6sHQ,gqPIHS-&-*=`Pm7_((%H$NR'%=4t>ra3F8Y;kr$,<ea:Rm<7A>ciCr\Xf;J)cM'$-q++-i93D`u%g+@p-Hf:=G5&;C:jW#hO":iQ@m$28H=oRcOY7;G>269D0`o?_KN!BPp$hm%0u)_74h954[<+H;-lbMYEh:;EU,ORJ=sfpI]&]Gg<#u&umV>89UtD/4$k67TJm4,GT.N`SFf2=K@!ikX>f@G`RU>'X/d>\OtEei@:gSCgBp.;e#VjX-&:ic!(Vi.j+#`;OEPSnR*Xe\+='))]4%6O;Y&<NGRL)6_:*V_YF_WCU[d9?pX'`VTVU)W0pBI^"p"5?W8'%@-6.DdCaH?3aHUGPK'frdcSogPq!]>HXoU)4-Yu$fC-O=$>Mc4;s%Cb&_;Caf>MJa1>Q+CbW=oWke'4]\R-qLWXc'aJ*UoX3!m?aC%`t*_aO(XiPrs905<J+L[%m.`sqR;\X)o%dnZiNJb[Ukm:p,f_@gjHLq+=6jWnE537#=eNMfrY^QT"OpD^dKPqAS,$6_^Q2-/_fA?fbpWNM1^S,G1ZN</[fB*n:ALK2`,[jAp%WIRL[LkJmY>iZj&?6otXXb@`lD0_R#1e+VG1A8-,4XW+;P_.Oh9UO(O\g'BYL;DqiRi2M0nRs\ID4r?D#Lg#YK?kece``.a_:6L(,_1)$Q"k.JFFE4TjD8Wkpl^-rl$%#kk>lOG6!4OfkkD%R7t@J`'K/jhBXLa:n.&G+!^pNNV]G\T-10Pap1R%A$j%T1nO@-U<l@dtX9V\e9G1%$J(!j&@J?6i)*QuoDT5!;FOQ_Mr&4pK7"NEI>,934!FEM8+4t7Y?2~>endstream
+endobj
+% 'R322': class PDFStream
+322 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2616 >>
+stream
+Gb!SmD/\/u')ipps'a8-k7fg!l<X//Nh'L,\929bm/[EK'tKM$9("IHU_MXg^R85fU0_Y7^$EX]Y[LWX3BK=KbVRQr6g3H(aFBs!i+`U;hhMbd@601J+7s"<&T4JL?[^njYe5D2LMf$f%IfdVmmFSjX7(X;V\aL]Y^ZNXXbQL8UL62(^bga!%.H%+V\M_<J<oQkO'TP(\+9g$s+'A.]_p+Rqka/PkC%8<@4u<[c!ucfP9:9<G]kZ?.[$IQ/<Qp]\]C&`%W4Mg:LP\Q&k!4d'J@E[Nc2,:bTW7NYo=6)Tb9(Q,if1#V1da&eM70!@jmkS/ea?U@#A%`UMP"+CM=?"XCrc'<9R%jZAR%4/7TEO>fLl6.;ZX4<^L?Fb\6XrJLdH@#R=DKb++fZTC^LV!81YPho^L.3>=N?[c-1P*1G<d2+d9?._CcNa5K[EAC0k.BVR4]-G_bU%[S+b(:!tfgfT:6@Z_%MKS+?k1#W\VIG_+'3.":WQ/C0LSO"T=mP1b]XPBa_@s:\(Bl?[R3'!pu`OFG*H>SQ08o>%a$>nYB086\OAHu[V<q76ij5IcQgJ=G+?LJ!c_]K0aO!^2W61^pnFnCu7Z,Cu-/l;[_M9srm_G"DBTO"]+8<m4iO`E=q]Z:J^O;1e:+bVIRlI[!i#Ok8B;*d4D!PM#^+E_3%EgkTOV;,O;;0%#'dUmn;\0[P&g5!W;'cX;49F@2dKrR%*'oVD&<2/pmJ+Jo*XV5>$q$'th4B?b8QZjMk#!PY:R..UDCRl:S_l_9&7-hZ(=dBVWEO[GaKk%-AX1Kf"@#c\r4A-`_fu:%m],I,/A=QsC_TJb($hPrM.hrjEn]"uk5a&o>EU'0ZJP1YboBd;FdiOX"A3!t+9*(U/n\s4746j:fKkGaPpCPDC0FYMn>]/MOH`SX>rHhn^m9La>n'cbS2*BCpb^>FY3U_2]3F$!P[.=jth3;&pl%*4.o/O'Z$/Go4F^IUNU^T,,Xqh1XG-1>srl.l8B[RU$%<DAO'M3``hjG[dN2C2@1LIm)i.M'6pM;9).MJm;[[$Vbl/F4:86kbjS[pdI^-65/gjRjLeT#gQ>?:8`h'S[1";DKFIttQlC&92+@4%_=fRTNJbUB$kLUTL>]EibY`oP-t./IBd'm*Tu`s%DMqai,OWZ6/Li0R4]VDl9Gr&VOeo],&RhsRC,ICf@8k(q*X+7Tmem(8*N#O^r-2aMggU-Eh'OQS>;f2h!,R$_ffE>sVr)haX@6K.q=6c7UNfF17,*1P-dHV%2;oLeITLa\Fr+c67L#IEDlPi4[,'tf'D)3H&O7bs/9Q;T%S4"!%'F^/H'P>.mqlI[3M66qD]R/ngo+&1\PN-&49p;<B%1u!en@SV,6n@O>Q>4=bu"\&[mXK/i<rCuPV]kq08j$sh8VeF3O3$t>`9P(RF>.Km\0ZK$Qds/f/mpLhf!bNX@U'CK!ah.\-^.%_dr=qpGZrT2AiP!4(:;G?dmAP0`=d,?=PSpP]$ND^2pD=890Gq5ai<'I.Pp?M?B22/.)og#L*\c4<+\f5Sj]=aQGMGp2EBG_J`tCW<Em8k?0#8le7NL@Fk*okOW$0-"i2uNoIlY38U_#QV@V)ajdC3;\0o3.@A[cJt,,u0;n1_YA]Uu:+`t&"16+s:D_mSOZ8&K4KX)msAZ,`C@@*Eigb]LB_]BI`6NKVnQQJJuhZI]V"BW$9ZXi8dra"CS8[bNhfrre^b)#cND:8l<$)Q20=5@j9QVL;22-Ju64pk+l1[%s&s.SC6t-Rp?rHsG(:$le:og@O9_J$)P)dK!0h3JXCW<k^2pA!"OpYqp2rb>@+qAfV]8'^ZRnSL:m.:P>#G,#ZR&Bq=9@m#!>M2D:sU*5EeBaa7=PG=&4kFiM8ml/T`:kR@=*nb<Zd:,&,q4?Q!>;N<U\=M'41-m7Yhm9"Sf%si`j\``LYq.k<fLV7*joJCgJXbJbJnud0#d0jRtiFp/iO]TTtm5Nd?mp=:@4%EbQVALV:8IW4cQ;Ls/TDFK$9UUen@rojoWXZU[E=%kkm@uT'4GW8&9%<FOWQV]>'aqOW.OIHd_U>9R4e0nj+C/O.bh"9N8nQ`'#s?r/NIp[",LIoM#PuVT1/d_,+jW11:bT#]$BET_TDpd%^uM_^5*sM*<[PY6XF71^^$#1[`Q#K*6\Rc#KN(CkE3rc0cZ.B&eR3R?H;]O#@hVTa-^F,.HiF>'o2M76aor^*[V$I7Lt.I(c1Nb[k:eE,P"!Z@2<C,RX6;6HVJI5<Q5N=COIVc<a`/HFPbnO'dZ6Kf=c7utGVgE5:J0+Q$V$Pl>E5X.Nj1HKg_*uL+6*`,DT41iWH/$%U)N7C^ohk<"Vu4sX(!Cf]SjeL)N9i,mbXL"e4iUH0D7Ink8Cs`Ja.CS_o\V%l38Xq9!'rWL/"r'j6!QZdr>A3ddkJUEMMukY<#kUAeG=,1E#oL]ZmD19b%ndMPUGR4$&V"1Jad0c&jq'Nh5!U/Mu%Q[9/@^Ba9#md,g0<M8Q']dcQ.i;E1F3J[0,([u#YkSJjWa-s.>Hh^@G`NVB/pU:89@*>R$"X7CE%VJ.))jAn_)^+_,h=j[\)oo#iG:0a<*Q1fNu3Gap-H4kSf;^rPh^\S`sR,$'~>endstream
+endobj
+% 'R323': class PDFStream
+323 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2886 >>
+stream
+Gb!;fD0+L@&cV29s+gOg,pQ97]pH+T)9&m#[8u9TkB8n/5<q?$%P^PF!V.N7qsFM2O$&OeSmo<kUld'5!UN#&GFf$lIXC4$S-&VmJFb]@GWmZZi.Xo3Mmr2%naaXHoAc+s;$ao)9I!fk)Y`16X2^[/)gHf7pFfn3Y$QP'e<s#T=JXl#%Sl'`FQ1f,kXa<QX#i<2]l.?L)_A]Za8]Ut5#i-.luOuQ,KFh'm9i[PIhRFs)Hlum,h9b^7.=I!a.=Pgauq"Ce00bM<0h<k.hN<5dtD]*I3l&QEOCrZAQd5cYuY,5A[3;rA.Zu"&sKM0Rdr#],Pe(/-WB1ao$jA%(Rn,C@[7Ci_-9rNnJW/ej[\.qFOjka]j17clqJMH)o;&Rc!_o^7,Ejg%bQek%=%2-Z@p0;;2K740ClNl+NJVN_dfqaHjMe?ko;#2iN)1^^ELOcKW6?_SN-H'9rE_)@]UM%Mp]U=r^"YQc.2QME30]XQ@Tj^DE:Z/9)t^.5m-qt7H"%=k5=B<VMW+\BE5n6Wq7)6;sC>N`ZLZM9VTo7PWnXL!8U\)n?ItB4&.,C"4khY/VDE3Ei'4u`m(lqp0?`20se8@a<eb[h'>,'eWMN+Kb3L3Y?6qJ^uAU87K/)a7aXW;Yi04i6"Ft5e8+IA3TTNOa+G]%S>gm[,a,eT=n)J2-"B@Ce=:?@?=Z\T`=b'[rlFMNVhkhk+bE@QCrJp>a7UmcC^Dgh&s1cs`E>CUIG)PHilmGPdEdXp2^1Zn=iP$HTb1=cZ`u=<ETt[DI%&V!"r2D=-Hc7-bqgJn"=d&+b,j9^__(%SI9fkaq=5465I:BWfTZD0n>_e8B<'$.*9pEL@&oeJ;P5o4/aWqrI`R%W-kbfH_gG$=U_7kq6R?YQ_H=2oe"/4r(bj0q%tC@,J&?=SoJM@$^VBc5GVJ;nFL:5k&Li$`Y^B4(`_O'(m'[.Ub3c+8e+M)'hIV;kGsFMO[&u^ij?.?9)ge/"XlbAh2$f[Eb7fM9Em27P]UBjIgE:>cmR)/Bk@&I:CHM&,RLDi2>JiiG%^%3/`W4k:"qcTB.nY\=n.'8)`8Q8I--\D?#<!PeY$SMs?0@lgiiohqgI&G_^E)5qh2g^S*]cAA$rQbFU2bNomHcMHh)f^O?dUdmn*22eF4Zh%3;@*,""u-C_o_gj7HQ]2,a_aO5I^NS[B16)'G4MtIdXu\NseD@e$WHO"L-h?@#V]4$''uQ9>ko03mm#&WR91VBfoQ[$5Wu\4*Q&oa8MD^O,.om,/W7pD%%<;7Uut%2_JmUjBE4+1.W90Q25(3E;fcJYo<fM]##mR35nE6FA?mVXL;'FK]U_;fO'9A![b#n_^khHgDY=Z'&R\o$E]f.f88K;XuNgZQ81'$)eD`kna9#e^C?kOQN[,LCKW(0<_jlpl8^BUJ*N:FMbCeGM;2JO;seG_G$kRc?#2Ds&Jpfe-](QOjJlfoo43!@`>o9;9"tWT=lbrbI4BoUGo"Q9>RHq?>\LGWs#fEna+>Db@VWVT1,[#G=t!"SEK9@+<oA]<*^6>'gC=61g5i//<ZhQ@W'VV0G(@#S0YN2:IX$hIRF!D=OH,U9[<IkeN=0!8H\V/^TTT$g)2@H<@;s;Th'ef;Al"E>Ff+cYQ>OoKRBkB,[O$8qQPLV&0T:U9*;8$#L^Y2kCtNM?iH'7V\Y904`akrVoWr+e4%ME7E.h(.B5+bkS@%spP@L2XT0RBU_b+=WC<[med)VX!^UO%9'4eC#-[We+"Cs"QS15ME@'tRs2.p#>UQnFkF5Uf*YD[mmAbK6h.94;jZ/i>1cM2gOmAil2Urg>.0SQj=p/oO*m!K$U9=`(%H#1kq.d@8!;49.V7(rcl;$u?HD<VR4>$=udRbqL63QU[*'"DXh5,JH[";<.6XXjb)^0H.HABaD@(f[gMeqheWI'A>o4VkP7$e/^^c:pX,V)9\XK-Cu$$4cM\nSkAs8+b4EhRK"364(5LMuZi[AmA^n9D4r(5hTVpW.8H'VpK,C=-kM8Ald^\9""!V+=V&Qnd&6gUE0pYjf4-=[6=%5I?>Ro&cR&.k--1e'?<2%97@Z"#on17'!<<2.8$3IM$!-bX;kY!N]V$F8lT]^D^h&$O*Z_(XJN!$BjbbIaIt<[*2TW7nd?n-5BFT*gC515THKM^ahN9id>cn*SSa(Dfb&/\M!a,>ZoG>lq)_k27TA,kk2`40n!Q*[ZVH8pWV7B.Tuij>M(9i$Ku1l1IS[56HJOsqAhoKmO1XghfmLfao7A9rL89d^Rq<C%/@HO(eri,aUV+X;8"HCRP/j`/JCdlL@aq@Q:HpL+P)Ym?d(H4FHhEEda6uJ:V*\<OTXo?c'n+eup]q=?qL+#$;r_S>=o+Z7$1-0M]\3uE'Kj?\BZmA>ga=@N2S6r<"1O=,W>p\\>4qs-#7F<a^IP-YAMn2iCH`d[Dt_t\rE8Qp%k5pSK]l19/>m`-*G-qOd?SU._D<Z'bp#tY=%X>W'pW%e43q&Is,F0h]Z/B;Kd=r2RTQc+'s.52kkn.OnU'h>1O+MNJNhg/AI&6Er\UE4fi=&&i#^.6fm!bp3OP$S2F?MB5D*XIoVqth7Os0-B6g3EJaY(fOGH))659&-bm+41ejmLgbT6G-A#q7,XDP//gpXg'hiASrRiMo,h3*0-GL4ZklfQ6[hnQk+3^@f9\hYUWBA\N>[Gc&*0^4:)S]C2mMHbKg0l^!^,A^rOpcm)7kJOdh6$B#URe'#NR1b7[,,*"$V?"_:[FAuhXBh,.Z(En@.V=2%n`DeT3:qlTcNreI^:to\fQ+=@5WZ,*YCZG6m6%?,7@EpMQ[q>aRZo^#_u1LcbH1WK!p,0K((>\Kq1e/<-&]BXGP#fq-1QNV_FlC61/J9Llo&%E"8<0V?i1^$oPl5~>endstream
+endobj
+% 'R324': class PDFStream
+324 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2692 >>
+stream
+Gau`UgN)%<&q+ths'abnD_VLuhSd[&f#k,;=XOuk>?c(gL;8n@#f+53"3K?%cflJN"=ZqeD3n1!\L:q6ds\h)oYn'Pi[<l<dmAk?/]9U*a!+9s@O:#R1_u#$ik*2$BCGXTDN7N4,"\N^"Rk]*+,d>_p:Fur*6$#fgc^,kWH!.0/@q3D`1df_*8rX5duC\I6<=Zma0*C>,^CgSIu;30q"e@npO2qtf0aCeanQ0bNpG'(H;:J^pHSH2`Og@QA(=,Rj$j6r:,MSupWAfM.q.bllU!W%o5E4gnaACEOit=02r[U0bs8A4/H%gN/!_[_Te[e?<&l>=&UpL.P@_0Z+!;abegaah1=P?R*ZI5Nij-e0d<MdnEh,h+:$JBBJ:8'kHdAS\1BQR0fSJ]f*.K/E!%5PdF96DC\/7C.]S!!jKokCs<*%oA>cf1!X9,JGV/5O<ptZ<nN.:Sb"lUo$%q=aB$fm5<Y"f4E3ZWZ0i"iODP1>Oo_*YS+*eEnQItX4Be%EtVU+QNT>N]!0F<T7nh\;KieL:tD<NZ[/H3Ot+f06\H6C_AKN?dr0NS97`3tK_FXK3jAE/,>p"cO>pL>G#STM?r%889/FicOrCo8g]dacCeoR3\[b_1+DDKRqFl4K#:J)a67H-j&'Q]nD/#4B%aQ"Cd)K,])1V8,*kR3C])B?>fRamtO@a2UVtmRl&*,kEXmA;(@hcfbF!HOefZM!9'=!iWEJ9\'ZWdaMKl,X91r'Y8MB(eTaMDnOaS>b(9?HQg93!5)guL=PjmH::g^g!/3%F1WNIF_imLoFs:nrS0ClaF%)t5$qb/:$R5+>aS])O.W;^P-,l4l%%o6_SVBjc>hZ0Bb"=:/Y.[jgj:<pmA6CBDGYg*KO<ZnrB>3Q8NQO>T[;TgK<5&FZ#=/G]lC2!>/c`-D&@405";DSX4AJe1m*Tc7S_p?B,YFr/=c!*'1aP/P!JuV&&`q2B'#_[Y>aq"nP6d[[VPml,,InNs7Ei##?#B3^PA0S6\[;n42jGl-^(/icM`#u6n6JCe:>AIB9oY5Bp)jW8c<5:jXBoa2-m#3Bj:P3[)cUjrl.,<6'M=q2.uF%uOJ3+',eMRkAP;@q9F(79,0fXo*\g]f_OPrqO+u'G'TW+=go4LM+s`fg8<p+hD8;6eU6=aMeL4P.Wq1V]J6@RoEV^H<IF%89VcHAZ"mZ_8AHU;hBIfTCI]ah_Ppm[[_-+g/rT[DH;AXI!b.:\)D@Y*S/?+O-UK%Mdg^jrCZ!)\q93d@7%35]PBuqTHIO$(R6m^5OaBPWbk,l(8*XfJQUF,JdfjQH'*\45iYC[D@h9ZnJKS`j&;CjHdFi/n^d.,lpoTG="bc:EF[WL0%4(E2\$#g,O7HQ1hFd:qY1RcMWG^]_9$n(*"`Pqcq71V7o3+a*%.4.I3!Q2k'&S_p0[GFoL-hSM)LXCKkEp"2Z^A[$dZVi'tMeF)gnM!RiUh_,m.[nS$ZMQ6jfB;;C30'l6&Ci"q+daeVJb9RL.+bX<fC*%'h\i\l"%e!se5.t78bXW<r5V_J/G:N6&?8eJcuaZ39*C[;kc1?gln[I_]l#M:QW^3-/C<8IG_0<&pu]';=5:a\BB2>g2Vmg620X@LV'sNFVLN<dIDDhu\:T(m*d%]E+Zbmkl,/FU?J!H25aGcR7Z%Pa<JSl:)jReE)c:eD]7&L5PFYS88)maNcsN<qWHs`\RL<)^)F0T]DKs77'#1EL4,/U1COMrpSi-j@CIM,.\SW92oYfN-'=/8cL')9/#`>MqMi2#@i7eYWKC$j_(Nn)=57Ob0_GH#%L\t-$\^td3gi0<"l_(sIA;A<)DcH4@O4GC)ik'lf,o8KGlniLBmq#MJmrF'5)ihK\d>gRJ<u?\<Ll1.N)P9cI&$k&R)l\(:!tFW`E'h4nI<S5/*u.HG^_Ok/Y>-ZmMcf#1P=b1%_MseTXkHjZO*WH">P')N(\><J*,"u=MFZn#/F(1_eHLHd"#5gP_lunR%#ArNhFU<`-VD/&gXI;)7B^@J9NmXbVajT>)aE"4I]`aE6u;(:W1heS`QZdl-F:IdZ$hQ5G]Z];QIH/)em<>Thb8;01SK[_Q)\ctNptb@.+mr@;'&>[_/9\^Rc@I4EFb]20pbM;W=_nB?tbgsg1q@*nPrklTa[.?crXZ`7_C<?ZQ=9%`9jrkKquK$SnT>$D*VTZ-]?,2(!PO=:$Vj-@Y[![lks)AHngY9+#P9lY(G7cAg:TFR8b:W42hYd&snc@Zrs>H_0;UG!<okA!k*'0W<1p(<0c91L^Q:$4,MbtB?LaDEpd/_N0b";1r>ucA\[@5NB8HT<-![&%nqa]:&B_*Ql3&V3.qa[F"a%Fh0NMc*XcY`0WUk]ik5b;`HO:p[E0X.>[0-[f'Y]W%=1YQTabq6rE5C@7fRr-\+%F^4KLHdTN"bc`Nn'?G)/=nm3,C:#dafLV4fWS)n"(G6RE$`MsCnoQmQlgO*9/;lG.++H1dlJrII'")<@V9dY8[Sk,totdAn"3Rra)GBgiQihT7?q\nd,@>NtZa^BseO(nNm:/'`d-T9!m"%Qduen!%U0K,2]ic7'i)k_;rU"#["W0<O;0B38P^Cf*%F\!-snMuZ4bH`BC3>X]?tl.^*W\EkfB:Y,5KqW(3IM>p:p89-Q?EO7N_*&r+kqJ%sa['.brF2rEWegScY]>&gpk9D=3kKj,/.TL2T~>endstream
+endobj
+% 'R325': class PDFStream
+325 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 1542 >>
+stream
+Gb!;cgN)%,&:O;3s'\DnElUL8;P^,^V,!Ii1/lea9g<1J5!UB,+TVT^!9MVcG6*ki-/TQK:",6E(L211Sis[k@#U_ns3+)c="4(B2Llp'[")ON-BS32DplOU)ugB$jm`JjOA'0>ZSNZ<.-S[lF;tHm%(CusG\XInBM)l.$u$#65]@XfG;i8gm&h?*O1p?W(`bp=):BW)ocO,+VYfDk^,=AYnr,R>gMl?@\MIf<s.^7FX'e!]VE)9V38'gMrpK8@64cR2S>/@VRD^oZNS_q^P&(@+>jU+mJC,%"FNIp0;H3o.V;Xi)>4Ht?[&O8TW9$VipuH:.%X39FR8LB;QoTmLfuu>:rCNTrH4O\rm(^O8V4aA8Nt/f]K$#(9L3,kpTF8Sdb76p"V>:S+5D,,.%@Z,&>dN5'S?isVE,A_a<\eAnSF)JC0QgAED;gf8-(It/^;I%_J<5_nNa;_Q]r>O+rcb^9%F(3!5<p$"`SgCZ+pC8Jksc8d"^=kEcBQm2Z\XR'kkI=Y`u_/Uj'WUnJ@hZ:3HKFWWiU.HZ1$#O,`]u/H5ZtZ0cEiNq)oRHOG&JFm#[Tu`20-I,/d_4%_*N=&1k>mEb[a#/lZ7tWFl*'%;*OKUL1eXM]E]S"?hA2lbgs=60'd7Fj>M(ag*4XglsE2)O#a3*Z$B_JL%]AeAD6(f#G!.9^=P:-TBf9P$n?eZ;<98nLe5mpkfNRY-'Y,RH[NdN^c``E0M?rV2o6.;TtBSPE1_;?&&$M5s.fS-+51ANP=/D6IJcr9WeiJO.k!:Kk/J5(Tj<X'%Iamgr[&o&;7jTD&tRm&9s-/j!SEX&2^rN>pplG/XP'.F>6q+_Q7;Q<C[<K(j/cYEA]ZqXH!]Rog^os8Xqo&m!#MuB.KiLLt%6$NS8iISm3:%Y&:(41cLCJX.g/1@K]tK1K\XS5V85+r?7'9B?Bo(68V5qa%h'g/HQ,QlSVpR]RiJN&sIF:N.jK&pW"MIPO\[<14uof%pM"5,<ATp]%8^67Ao'G%$XEV;QY=X0NMn6h7kZ1i,sNm4FJ!iIo+jhXLA[We_R3/;`VF\V?=l8OK)TI;kX]3L"I&IKd?0"ZE2G>l]3l'1Kn["Wf?SW[E'JtmAV$^]2P5I5NTkC1NQ@;qA5#\&s:k*$H6Mj7Um)(+kHP-H-!@9C@6E?)QABQ-@NCZ"BnpG&o5RO)QYX:0ha:d,-e)9V@n)ol[YWt8P_KKs1HW.#[T4.9@hWs]E:q[Ok9S-f6#Q;]uZbOJ_\5E$dn:K+6.r_`CaG.YXtKVJ_cn.C::Ia(F?6U;2(io^%:YO^/N@dI\M1\;f)Wi'M+9\PB(9=_]#trgpZG']=%e<qp7KB5l=2XnpIT;^Q;llk)6EW.OO-PS$\G(6)ZO)#f3A%D-\t/a>8hEU[QPIR70(V9Q<Mm&.QMpR4$HFA,\(VGLbcLWdT9#eiuq4Q.7Mb5\njZNJVR^mod4hXC#YY7tRL_:K7A$a9:&+fK=/E6G'.Lp3K^6IYf"BZh@D-7[%*BI+^A(=1CM5X$56fAah.S^u<+:MD\]]~>endstream
+endobj
+% 'R326': class PDFStream
+326 0 obj
+% page stream
+<< /Filter [ /ASCII85Decode
+ /FlateDecode ]
+ /Length 2069 >>
+stream
+Gb!;fgMYb*&:H4YIi.7CcGJ.9GIqcb[RD!G[[4N$PS[MtD)RQUP#>Qbr=2D%^*]/PMOVIPi/eR34<0qQ6dg]QIVesA8c^P7nE5-;C^3ECYW^0^d78F?HN!,arn>o_^'B[.Kg*5W;/SbI?C"`&hmFIHk-&-#X*3;rBFP"b7OcuuL"4hil7oYneR`*;`"Y7mG7LD:0`".\s$_Ee/:W'#[O/?`9DA.96.ha_pO_@a7CH\dJK#N&L/ou6/$g5">t_T:@G+)@dk#)qi<"=ER?Y):]U6NkaoXa7*mqJ3oF^+B/J!H[o%_5]mf0gP*4Kjs9b8Aj-sZ:!-NtHqKG=kNKU\,>'Nc+sAP=C<7,m*57LFtH4V]XtP"!0-.e#lu!M<aOKo7JtSAk!jrRIh3lSVp"56#K9#<o'\EYfuZ9\4$I"L>tG'Cdn21D]50-00Xo4Q6[+BecMBK:(N%Lrq>(1koNY0<bd1AWeU;5hfu]irrfuL&P/*.'nkD;a<-ql?\oGWY#VoSk8dRUfig2\lC2`1f%eBA]BDWZKlEf,9Vj(O:s)9J7iFcZC\l54'i@fFffI=Ndr_)8?fA)N@'$j2>7M40Y[=0MbL[sQFSsu35]D]@]"l_O6]EKJ0YIE+F1]nO;NI`2uk.cocu0o_MQNdV\.4/TSU,CD:Ob6n<m+e2<W/NIG5_]a1$d.QHakHepnSe?tqM>XQ\Hn@AkbVB'kB/i7nleU:`Es0fmU/a/^4^!A!uAQkMl(>d>W0Jh*`XmbSqd^3u)S2E>bjfll+p4U0`B_aE'JRM53FF<hH_`!a)upcPV(MCP&fBGV5*`E<=A*n(6=Ju9OLrN2'YSd%P7]q-B6L(m&69_V@^`0BlgCk!s2S#2`[J'e3!KV2HU=6kMHWSg1Gj:X$iDaT7l[6pR#J.4E@NX90LX$&s6@.uK\2!70^mot6[.(8ku0,P+@@sd)?LK/!uXS'YPE*+4[%5#_-S,[[Z$^)dU9qLeV<r[]@X\k6u[7NoURTVPIhBMb9gbT"M;K>8Xig4T-H6HEcpD).I\<m]L2oc;KfAM0kCCMqp<P0g]fRm9@27<>UPl!-,7UoQ5iUEMP[g%b;>$/5Nh@ic>XUU!i_cnW*Tb[,jlCiq`KG(3k^oTdZ+-#HS:;+#-'d$#87C+RKpqZNF@6S2CQJ@Oh,T)?t,Ndjj&&u:!8eh;'_'TPb)YP<WP[UhIU(j!a+H/0W?/S%<iA<2]Lb0o:2ois9HGkafI&`qr^:<^i'4K_!74E8?W,(s9_LrP*.em>PB7Z%4j+cO])L\Y4[?5<W?<8W&;Bf'T<%=pDr47IV]>iH<,rt\=;+2RQ+$st'&L2$bY\]5[DEF\"-;`;N.rWap!3Un2I%_/IdmHMSYm;[I.4Yp59))m]e-e+R`G1e(InCa5%1hm\[0F"i.aU*gJ[#$/Uf3:V;G*c2dj:HI7'deX"kiiT*8m:Y/!h#.U6lU.RSQdP$S3]dacKcJ4!"(kXl=SjE(Te?2!n^8V6Y,8+gjsX)cT5)>3pXp.BNsCDE:9QL`u(pA/V`]iO;K6a>KSoD/*`Klb[BS<tA]=>@<Rm3'S"NSQ_r-p;@7O_fA!4X4hM^hti81j`HHGE;[MW:Sg""$Rt%ZcKXnbB9Elhdea/>_Jt=.b?UW-8aJk>kEHTTh]?`u1lg;II[Ngf=,I9]n",R4Sm=`H89u4)ifZ]RLg3^*&Y;$Oj=mE![EB#69W<7\L-)edkT5t&m01S7Zr[^0q7`*\%8N8cZlAg[\B4=F5MPj,Q_h&.r*B`>Cd>L/4*1rbMs%VOnII;:><Q4H7O:l:)OQY6Fm,:BlL)Q;`Xj\T,V`qAdca8Nf0If@aup/lqR*Wk(4G<sQOTuO>]j[Fd(%;/OqmhYWjFr[jLK#q,fVN%rbbKTeCH)>de5e?gp8[]'T1E&>hmHO<#O;[cY*M!W]=*6C(-h$o7TQ6crVV`ateC7iO5MAId1dj-"5@oWkig.A0R0^kZ06EEd$3J4hj-==K"%&Wb"aXc)P9$D(7N*rh1AiQ56KQGKN9'\CE/?F@1H_@n\&D!p)q0AeMYc?LaCA_Wt;'!RC6PAH~>endstream
+endobj
+xref
+0 327
+0000000000 65535 f
+0000000113 00000 n
+0000000263 00000 n
+0000000469 00000 n
+0000012253 00000 n
+0000012440 00000 n
+0000012682 00000 n
+0000012912 00000 n
+0000013142 00000 n
+0000013371 00000 n
+0000013598 00000 n
+0000013826 00000 n
+0000014058 00000 n
+0000014289 00000 n
+0000014521 00000 n
+0000014752 00000 n
+0000014982 00000 n
+0000015214 00000 n
+0000015444 00000 n
+0000015676 00000 n
+0000015908 00000 n
+0000016138 00000 n
+0000016368 00000 n
+0000016600 00000 n
+0000016832 00000 n
+0000017063 00000 n
+0000017295 00000 n
+0000017525 00000 n
+0000017756 00000 n
+0000017986 00000 n
+0000018218 00000 n
+0000018450 00000 n
+0000018682 00000 n
+0000018914 00000 n
+0000019146 00000 n
+0000019376 00000 n
+0000019608 00000 n
+0000019839 00000 n
+0000020071 00000 n
+0000020303 00000 n
+0000020535 00000 n
+0000020765 00000 n
+0000020998 00000 n
+0000021229 00000 n
+0000021461 00000 n
+0000021693 00000 n
+0000021925 00000 n
+0000022138 00000 n
+0000022876 00000 n
+0000023105 00000 n
+0000023336 00000 n
+0000023567 00000 n
+0000023798 00000 n
+0000024029 00000 n
+0000024259 00000 n
+0000024490 00000 n
+0000024720 00000 n
+0000024952 00000 n
+0000025182 00000 n
+0000025414 00000 n
+0000025646 00000 n
+0000025878 00000 n
+0000026109 00000 n
+0000026340 00000 n
+0000026571 00000 n
+0000026803 00000 n
+0000027035 00000 n
+0000027265 00000 n
+0000027496 00000 n
+0000027727 00000 n
+0000027958 00000 n
+0000028189 00000 n
+0000028421 00000 n
+0000028653 00000 n
+0000028882 00000 n
+0000029114 00000 n
+0000029345 00000 n
+0000029577 00000 n
+0000029808 00000 n
+0000030038 00000 n
+0000030268 00000 n
+0000030498 00000 n
+0000030727 00000 n
+0000030957 00000 n
+0000031187 00000 n
+0000031418 00000 n
+0000031646 00000 n
+0000031877 00000 n
+0000032108 00000 n
+0000032323 00000 n
+0000032992 00000 n
+0000033228 00000 n
+0000033462 00000 n
+0000033697 00000 n
+0000033951 00000 n
+0000034219 00000 n
+0000034464 00000 n
+0000034736 00000 n
+0000035027 00000 n
+0000035304 00000 n
+0000035578 00000 n
+0000035860 00000 n
+0000036139 00000 n
+0000036407 00000 n
+0000036671 00000 n
+0000036928 00000 n
+0000037179 00000 n
+0000037430 00000 n
+0000037727 00000 n
+0000038020 00000 n
+0000038303 00000 n
+0000038619 00000 n
+0000038909 00000 n
+0000039194 00000 n
+0000039483 00000 n
+0000039765 00000 n
+0000040045 00000 n
+0000040337 00000 n
+0000040620 00000 n
+0000040918 00000 n
+0000041202 00000 n
+0000041475 00000 n
+0000042076 00000 n
+0000042373 00000 n
+0000042667 00000 n
+0000042965 00000 n
+0000043283 00000 n
+0000043570 00000 n
+0000043856 00000 n
+0000044119 00000 n
+0000044358 00000 n
+0000044580 00000 n
+0000044758 00000 n
+0000044980 00000 n
+0000045166 00000 n
+0000045385 00000 n
+0000045780 00000 n
+0000046053 00000 n
+0000046343 00000 n
+0000046566 00000 n
+0000046878 00000 n
+0000047119 00000 n
+0000047361 00000 n
+0000047603 00000 n
+0000047845 00000 n
+0000048072 00000 n
+0000048270 00000 n
+0000048510 00000 n
+0000048750 00000 n
+0000048992 00000 n
+0000049234 00000 n
+0000049476 00000 n
+0000049718 00000 n
+0000049958 00000 n
+0000050181 00000 n
+0000050613 00000 n
+0000050836 00000 n
+0000051148 00000 n
+0000051390 00000 n
+0000051624 00000 n
+0000051866 00000 n
+0000052107 00000 n
+0000052349 00000 n
+0000052591 00000 n
+0000052832 00000 n
+0000053056 00000 n
+0000053438 00000 n
+0000053678 00000 n
+0000053917 00000 n
+0000054156 00000 n
+0000054380 00000 n
+0000054706 00000 n
+0000054996 00000 n
+0000055238 00000 n
+0000055476 00000 n
+0000055715 00000 n
+0000055938 00000 n
+0000056280 00000 n
+0000056518 00000 n
+0000056742 00000 n
+0000057064 00000 n
+0000057305 00000 n
+0000057530 00000 n
+0000057852 00000 n
+0000058093 00000 n
+0000058334 00000 n
+0000058575 00000 n
+0000058800 00000 n
+0000059142 00000 n
+0000059367 00000 n
+0000059679 00000 n
+0000059921 00000 n
+0000060162 00000 n
+0000060387 00000 n
+0000060719 00000 n
+0000060960 00000 n
+0000061185 00000 n
+0000061491 00000 n
+0000061781 00000 n
+0000062019 00000 n
+0000062258 00000 n
+0000062495 00000 n
+0000062718 00000 n
+0000063060 00000 n
+0000063298 00000 n
+0000063521 00000 n
+0000063843 00000 n
+0000064083 00000 n
+0000064322 00000 n
+0000064628 00000 n
+0000064903 00000 n
+0000065045 00000 n
+0000065289 00000 n
+0000065418 00000 n
+0000065624 00000 n
+0000065781 00000 n
+0000065953 00000 n
+0000066122 00000 n
+0000066335 00000 n
+0000066506 00000 n
+0000066735 00000 n
+0000066894 00000 n
+0000067074 00000 n
+0000067258 00000 n
+0000067448 00000 n
+0000067630 00000 n
+0000067813 00000 n
+0000067980 00000 n
+0000068166 00000 n
+0000068390 00000 n
+0000068559 00000 n
+0000068728 00000 n
+0000068918 00000 n
+0000069094 00000 n
+0000069285 00000 n
+0000069504 00000 n
+0000069659 00000 n
+0000069836 00000 n
+0000070006 00000 n
+0000070176 00000 n
+0000070339 00000 n
+0000070534 00000 n
+0000070763 00000 n
+0000070921 00000 n
+0000071099 00000 n
+0000071277 00000 n
+0000071454 00000 n
+0000071613 00000 n
+0000071801 00000 n
+0000072028 00000 n
+0000072239 00000 n
+0000072408 00000 n
+0000072587 00000 n
+0000072774 00000 n
+0000072956 00000 n
+0000073128 00000 n
+0000073349 00000 n
+0000073506 00000 n
+0000073691 00000 n
+0000073871 00000 n
+0000074036 00000 n
+0000074251 00000 n
+0000074413 00000 n
+0000074590 00000 n
+0000074758 00000 n
+0000074932 00000 n
+0000075106 00000 n
+0000075282 00000 n
+0000075457 00000 n
+0000075621 00000 n
+0000075846 00000 n
+0000076004 00000 n
+0000076189 00000 n
+0000076363 00000 n
+0000076553 00000 n
+0000076727 00000 n
+0000076942 00000 n
+0000077109 00000 n
+0000077293 00000 n
+0000077477 00000 n
+0000077643 00000 n
+0000077869 00000 n
+0000078044 00000 n
+0000078218 00000 n
+0000078367 00000 n
+0000078552 00000 n
+0000078786 00000 n
+0000078944 00000 n
+0000079132 00000 n
+0000079317 00000 n
+0000079496 00000 n
+0000079733 00000 n
+0000079905 00000 n
+0000080081 00000 n
+0000080251 00000 n
+0000080431 00000 n
+0000080603 00000 n
+0000080827 00000 n
+0000080991 00000 n
+0000081179 00000 n
+0000081367 00000 n
+0000081580 00000 n
+0000081720 00000 n
+0000082060 00000 n
+0000083987 00000 n
+0000085644 00000 n
+0000089104 00000 n
+0000092473 00000 n
+0000095769 00000 n
+0000098441 00000 n
+0000101022 00000 n
+0000103803 00000 n
+0000106574 00000 n
+0000109611 00000 n
+0000113392 00000 n
+0000117597 00000 n
+0000120616 00000 n
+0000123725 00000 n
+0000126396 00000 n
+0000129393 00000 n
+0000131807 00000 n
+0000134643 00000 n
+0000137832 00000 n
+0000140593 00000 n
+0000143624 00000 n
+0000146461 00000 n
+0000148148 00000 n
+trailer
+<< /ID
+ % ReportLab generated PDF document -- digest (http://www.reportlab.com)
+ [(\262~\267\007\250\024\326\216\224D*%\324\240\2522) (\262~\267\007\250\024\326\216\224D*%\324\240\2522)]
+
+ /Info 211 0 R
+ /Root 210 0 R
+ /Size 327 >>
+startxref
+150334
+%%EOF
diff --git a/pdk/docs/compatibility/android-cts-manual-r4.pdf b/pdk/docs/compatibility/android-cts-manual-r4.pdf
new file mode 100644
index 0000000..f16b6f9
--- /dev/null
+++ b/pdk/docs/compatibility/android-cts-manual-r4.pdf
Binary files differ
diff --git a/pdk/docs/compatibility/compatibility_toc.cs b/pdk/docs/compatibility/compatibility_toc.cs
index 5688d14..183c0de 100644
--- a/pdk/docs/compatibility/compatibility_toc.cs
+++ b/pdk/docs/compatibility/compatibility_toc.cs
@@ -7,12 +7,13 @@
<ul>
<li><h2>Getting Started</h2><ul>
<li><a href="<?cs var:toroot ?>compatibility/overview.html">Compatibility Overview</a></li>
- <li><a href="">Current CDD</a></li>
+ <li><a href="<?cs var:toroot ?>compatibility/android-2.3-cdd.pdf">Current CDD</a></li>
<li><a href="<?cs var:toroot ?>compatibility/cts-intro.html">CTS Introduction</a></li>
+ <li><a href="<?cs var:toroot ?>compatibility/cts-development.html">CTS Development</a></li>
</ul></li>
<li><h2>More Information</h2><ul>
- <li><a href="<?cs var:toroot ?>downloads/index.html">Downloads</a></li>
+ <li><a href="<?cs var:toroot ?>compatibility/downloads.html">Downloads</a></li>
<li><a href="<?cs var:toroot ?>faqs.html#compatibility">FAQs</a></li>
<li><a href="<?cs var:toroot ?>compatibility/contact-us.html">Contact Us</a></li>
</ul></li>
diff --git a/pdk/docs/compatibility/contact-us.jd b/pdk/docs/compatibility/contact-us.jd
index ba4e887..2aa2aa1 100644
--- a/pdk/docs/compatibility/contact-us.jd
+++ b/pdk/docs/compatibility/contact-us.jd
@@ -7,13 +7,12 @@
out of any of these options, please first read "Getting the Most from Our
Lists" on the <a href="{@docRoot}community/index.html">Community page.</a></p>
-<h3>Discussion Group</h3>
+<h3>For General Discussion</h3>
<p>The preferred way to reach us is via the <a
-href="http://groups.google.com/group/android-compatibility">android-compatibility
-mailing list</a>. Use this list for all your compatibility-related questions.
-Please be aware that this is a public forum.</p>
+href="mailto:compatibility@android.com">compatibility@android.com
+address</a>.</p>
-<h3>CTS Technical Questions</h3>
+<h3>For CTS Technical Questions</h3>
<p>If you have specific issues with the Compatibility Test Suite that require
you to disclose information you'd prefer not to be public, you can contact an
email address we've set up specifically this purpose: <a
@@ -23,9 +22,9 @@
list. Note also that this list is for specific technical questions; general
inquiries will also be directed back to the android-compatibility list.</p>
-<h3>Private Inquiries</h3>
+<h3>For Business Inquiries</h3>
<p>Finally, business inquiries about the compatibility program, including
requests to use branding elements and so on, can be sent to the address <a
-href="mailto:compatibility@android.com">compatibility@android.com</a>. Like
+href="mailto:android-partnerships@google.com">android-partnerships@google.com</a>. Like
the CTS address, this address is for specific, private inquiries; general
questions will be directed back to the android-compatibility list.</p>
diff --git a/pdk/docs/compatibility/cts-development.jd b/pdk/docs/compatibility/cts-development.jd
new file mode 100644
index 0000000..7a2f5af
--- /dev/null
+++ b/pdk/docs/compatibility/cts-development.jd
@@ -0,0 +1,130 @@
+page.title=CTS Development
+doc.type=compatibility
+@jd:body
+
+<h3>Initializing Your Repo Client</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/download.html">instructions</a>
+to get and build the Android source code but specify "-b froyo"
+when issuing the "repo init" command. This assures that your CTS
+changes will be included in the next CTS release and beyond.</p>
+
+<h3>Setting Up Eclipse</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/using-eclipse.html">instructions</a>
+to setup Eclipse but execute the following command to generate the
+.classpath file rather than copying the one from the development
+project:</p>
+
+<pre>
+cd /path/to/android/root
+./cts/development/ide/eclipse/genclasspath.sh > .classpath
+chmod u+w .classpath
+</pre>
+
+<p>This .classpath file will contain both the Android framework
+packages and the CTS packages.</p>
+
+<h3>Building and Running CTS</h3>
+
+<p>Execute the following commands to build CTS and start the interactive
+CTS console:</p>
+
+<pre>
+cd /path/to/android/root
+make cts
+cts
+</pre>
+
+<p>Provide arguments to CTS to immediately start executing a test:</p>
+
+<pre>
+cts start --plan CTS -p android.os.cts.BuildVersionTest
+</pre>
+
+<h3>Writing CTS Tests</h3>
+
+<p>CTS tests use JUnit and the Android testing APIs. Review the
+<a href="http://d.android.com/guide/topics/testing/testing_android.html">Testing
+and Instrumentation</a> tutorial while perusing the existing tests under the
+"cts/tests/tests" directory. You will see that CTS tests mostly follow the same
+conventions used in other Android tests.</p>
+
+<p>Since CTS runs across many production devices, the tests must follow
+these rules:</p>
+
+<ul>
+ <li>Must take into account varying screen sizes, orientations, and
+ keyboard layouts.</li>
+ <li>Only use public API methods. In other words, avoid all classes,
+ methods, and fields that are annotated with the "hide" annotation.</li>
+ <li>Avoid relying upon particular view layouts or depend on the
+ dimensions of assets that may not be on some device.</li>
+ <li>Don't rely upon root privileges.</li>
+</ul>
+
+<h4>Test Naming and Location</h4>
+
+<p>Most CTS test cases target a specific class in the Android API. These tests
+have Java package names with a "cts" suffix like "android.view.cts" and class
+names with the "Test" suffix like "ViewTest." Each test case consists of
+multiple tests, where each test usually exercises a particular API method of
+the API class being tested. Each test is annotated with a @TestTargetNew
+annotation to indicate what API method is being exercised. These tests are
+arranged in a directory structure where tests are grouped into different
+categories like "widgets" and "views."</p>
+
+<p>For example, the CTS test for "android.widget.TextView" is
+"android.widget.cts.TextVietTest" found under the
+"cts/tests/tests/widget/src/android/widget/cts" directory with its
+Java package name as "android.widget.cts" and its class name as
+"TextViewTest." The "TextViewTest" class has a test called "testSetText"
+that exercises the "setText" method and a test named "testSetSingleLine" that
+calls the "setSingleLine" method. Each of those tests have @TestTargetNew
+annotations indicating what they cover.</p>
+
+<p>Some CTS tests do not directly correspond to an API class but are placed in
+the most related package possible. For instance, the CTS test,
+"android.net.cts.ListeningPortsTest," is in the "android.net.cts," because it
+is network related even though there is no "android.net.ListeningPorts" class.
+Thus, use your best judgement when adding new tests and refer to other tests
+as examples.</p>
+
+<h4>New Test Packages</h4>
+
+<p>When adding new tests, there may not be an existing directory to place your
+test. In that case, refer to the example under "cts/tests/tests/example" and
+create a new directory. Furthermore, make sure to add your new package's
+module name from its Android.mk to "CTS_COVERAGE_TEST_CASE_LIST" in
+"cts/CtsTestCaseList.mk." This Makefile is used by "build/core/tasks/cts.mk"
+to glue all the tests together to create the final CTS package.</p>
+
+<h4>Test Stubs and Utilities</h4>
+
+<p>Some tests use additional infrastructure like separate activities
+and various utilities to perform tests. These are located under the
+"cts/tests/src" directory. These stubs aren't separated into separate test
+APKs like the tests, so the "cts/tests/src" directory does not have additional
+top level directories like "widget" or "view." Follow the same principle of
+putting new classes into a package with a name that correlates to the purpose
+of your new class. For instance, a stub activity used for testing OpenGL like
+"GLSurfaceViewStubActivity" belongs in the "android.opengl.cts" package under
+the "cts/tests/src/android/opengl" directory.</p>
+
+<h3>Other Tasks</h3>
+
+<p>Besides adding new tests there are other ways to contribute to CTS:</p>
+
+<ul>
+ <li>Fix or remove tests annotated with BrokenTest and KnownFailure.</li>
+</ul>
+
+<h3>Submitting Your Changes</h3>
+
+<p>Follow the
+<a href="{@docRoot}source/submit-patches.html">Android
+contributors' workflow</a> to contribute changes to CTS. A reviewer
+will be assigned to your change, and your change should be reviewed shortly!</p>
+
diff --git a/pdk/docs/compatibility/cts-intro.jd b/pdk/docs/compatibility/cts-intro.jd
index f1d2359..5d80a45 100644
--- a/pdk/docs/compatibility/cts-intro.jd
+++ b/pdk/docs/compatibility/cts-intro.jd
@@ -13,10 +13,14 @@
<h3>Workflow</h3>
<ol>
-<li>Obtain the CTS source code. The CTS is included in the Android source code available from the Android
-Open Source Project. (To get a copy of that source code, <a
-href="{@docRoot}source/download.html">read this page.</a></li>
+<li><a href="{@docRoot}compatibility/downloads.html">Download</a> the CTS.
<li>Attach at least one device (or emulator) to your machine.</li>
+<li>For CTS 2.1 R2 and beyond, setup your device (or emulator) to run the accessibility tests:
+ <ol>
+ <li>adb install -r android-cts/repository/testcases/CtsDelegatingAccessibilityService.apk</li>
+ <li>On the device, enable Settings > Accessibility > Accessibility > Delegating Accessibility Service</li>
+ </ol>
+</li>
<li>Launch the CTS. The CTS test harness loads the test plan onto the attached devices. For each test in the test harness:
<ul>
<li>The test harness pushes a .apk file to each device, executes the test through instrumentation, and records test results.</li>
diff --git a/pdk/docs/compatibility/downloads.jd b/pdk/docs/compatibility/downloads.jd
new file mode 100644
index 0000000..61bdfd9
--- /dev/null
+++ b/pdk/docs/compatibility/downloads.jd
@@ -0,0 +1,60 @@
+page.title=Android Compatibility Downloads
+doc.type=compatibility
+@jd:body
+<p>Thanks for your interest in Android Compatibility! The links below allow
+you to access the key documents and information.</p>
+
+<h2>Android 2.3</h2>
+<p>Android 2.3 is the release of the development milestone code-named
+Gingerbread. Android 2.3 is the current version of Android. Source code for
+Android 2.3 is found in the 'gingerbread' branch in the open-source tree. A
+CTS release for Android 2.3 has not yet been prepared, but one will be
+available soon.
+</p>
+<ul>
+ <li><a href="{@docRoot}compatibility/android-2.3-cdd.pdf">Android 2.3 Compatibility Definition Document (CDD)</a></li>
+ <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.3_r1-x86.zip">Android 2.3 R1 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 2.2</h2>
+<p>Android 2.2 is the release of the development milestone code-named
+FroYo. Source code for Android 2.2 is found in the 'froyo' branch in the
+open-source tree.
+</p>
+<ul>
+ <li><a href="{@docRoot}compatibility/android-2.2-cdd.pdf">Android 2.2 Compatibility Definition Document (CDD)</a></li>
+ <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.2_r4-x86.zip">Android 2.2 R4 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 2.1</h2>
+<p>Android 2.1 is the release of the development milestone code-named
+Eclair. Source code for Android 2.1 is found in the 'eclair' branch in the
+open-source tree. Note that for technical reasons, there is no compatibility
+program for Android 2.0 or 2.0.1, and new devices must use Android 2.1.
+</p>
+<ul>
+ <li><a href="{@docRoot}compatibility/android-2.1-cdd.pdf">Android 2.1 Compatibility Definition Document (CDD)</a></li>
+ <li><a href="http://dl.google.com/dl/android/cts/android-cts-2.1_r5-x86.zip">Android 2.1 R5 Compatibility Test Suite (CTS)</a></li>
+</ul>
+
+<h2>Android 1.6</h2>
+<p>Android 1.6 was the release of the development milestone code-named Donut.
+Android 1.6 was obsoleted by Android 2.1. Source code for Android 1.6 is found
+in the 'donut' branch in the open-source tree.
+<ul>
+ <li><a href="{@docRoot}compatibility/android-1.6-cdd.pdf">Android 1.6 Compatibility Definition Document (CDD)</a></li>
+</ul>
+
+<h2>Compatibility Test Suite Manual</h2>
+<p>The CTS user manual is applicable to any CTS version, but CTS 2.1 R2 and
+beyond require
+<a href="{@docRoot}compatibility/cts-intro.html">additional steps</a>
+to run the accessibility tests.
+<ul>
+ <li><a href="{@docRoot}compatibility/android-cts-manual-r4.pdf">Compatibility Test Suite (CTS) User Manual</a></li>
+</ul>
+
+<h2>Older Android Versions</h2>
+<p>There is no Compatibility Program for older versions of Android, such as Android
+1.5 (known in development as Cupcake). New devices intended to be Android
+compatible must ship with Android 1.6 or later.</p>
diff --git a/pdk/docs/compatibility/index.jd b/pdk/docs/compatibility/index.jd
index 0c39a98..e4e30a8 100644
--- a/pdk/docs/compatibility/index.jd
+++ b/pdk/docs/compatibility/index.jd
@@ -1,17 +1,21 @@
page.title=Android Compatibility
doc.type=compatibility
@jd:body
-<p>Android is an open source product, and anyone can use the source code to build
-devices. The purpose of the Android compatibility program is to help Android
-device implementations remain compatible with all apps.</p>
-<p>A device is considered compatible if existing and new third-party
-applications run correctly on it. Poor device implementations that change APIs
-or alter behaviors will break these apps and so are not compatible. The
-Android compatibility program's aim is to ensure that these APIs are
-consistently implemented across devices.</p>
-<p>The latest version of the Android source code and compatibility program is
-1.6, which roughly corresponded to the Donut branch. The compatibility
-program for Android 2.x (corresponding to Eclair) is coming soon.</p>
+<p>Android's purpose is to establish an open platform for developers to build
+innovative mobile apps. Three key components work together to realize this
+platform.</p>
+<p>The Android Compatibility Program defines the technical details of Android
+platform and provides tools used by OEMs to ensure that developers’ apps run
+on a variety of devices. The Android SDK provides built-in tools that
+Developers use to clearly state the device features their apps require. And
+Android Market shows apps only to those devices that can properly run
+them.</p>
+<p>These pages describe the Android Compatibility Program and how to get
+access to compatibility information and tools. The latest version of the
+Android source code and compatibility program is 2.3, which
+corresponded to the Gingerbread branch.</p>
+
+
<h2>Why build compatible Android devices?</h2>
<h3>Users want a customizable device.</h3>
<p>A mobile phone is a highly personal, always-on, always-present gateway to
@@ -20,7 +24,7 @@
platform for running after-market applications.</p>
<h3>Developers outnumber us all.</h3>
-<p>No device manufacturer can hope to write all the software that anyone could
+<p>No device manufacturer can hope to write all the software that a person could
conceivably need. We need third-party developers to write the apps users want,
so the Android Open Source Project aims to make it as easy and open as
possible for developers to build apps.</p>
@@ -38,30 +42,23 @@
sure your device is compatible with Android. For more details about the
Android compatibility program in general, see <a
href="{@docRoot}compatibility/overview.html">the program overview</a>.</p>
-<p>Building a compatible device is a four-step process:</p>
+<p>Building a compatible device is a three-step process:</p>
<ol>
- <li><b>Obtain the Android software stack source code</b><p>This is the
+ <li><b>Obtain the Android software source code</b><p>This is the
<a href="{@docRoot}source/index.html">source code for the Android
platform</a>, that you port to your hardware.</p></li>
- <li><b>Comply with Android Compatibility Definition Document</b><p>
- This document enumerates the software and the hardware features of
+ <li><b>Comply with Android Compatibility Definition Document (CDD)</b><p>
+ The CDD enumerates the software and hardware requirements of
a compatible Android device.</p></li>
<li><b>Pass the Compatibility Test Suite (CTS)</b><p>You can use the CTS
(included in the Android source code) as an ongoing aid to compatibility
during the development process.</p></li>
- <li><b>Submit CTS report</b><p>[Optional] You can also submit your CTS report,
- so that it can be validated and recorded.</p><p><i>Note:
- the submission system is currently under construciton, and is not currently
- available.</i></p></li>
</ol>
-<h2>Benefits of compatibility</h2>
-<p>By submitting a validated CTS report, you receive public recognition of
-your device's compatibility. This also opens up additional options you can
-pursue such as use of the Android branding, access to Android Market, and
-more.</p>
-<p>As a consequence of some legal quirks, we aren't able to offer automatic
-licensing of either the Android Market or branding. To actually obtain access
-to these programs, you will need to <a
-href="{@docRoot}compatibility/contact-us.html">contact us</a> to obtain a
-license.</p>
+<h2>Joining the Ecosystem</h2>
+<p>Once you've built a compatible device, you may wish to include Android
+Market to provide your users access to the third-party app ecosystem.
+Unfortunately, for a variety of legal and business reasons, we aren't able to
+automatically license Android Market to all compatible devices. To inquire
+about access about Android Market, you can <a
+href="{@docRoot}compatibility/contact-us.html">contact us</a></p>
diff --git a/pdk/docs/compatibility/overview.jd b/pdk/docs/compatibility/overview.jd
index 039e2c2..31a4832 100644
--- a/pdk/docs/compatibility/overview.jd
+++ b/pdk/docs/compatibility/overview.jd
@@ -35,11 +35,13 @@
compatible.</p></li>
<li><b>Minimize costs and overhead associated with
compatibility.</b><p>Ensuring compatibility should be easy and inexpensive to
-device manufacturers. The testing tool (CTS) is free and will soon be available
-in open source. CTS is designed to be used for continuous self-testing during
-the device development process to eliminate the cost of changing your workflow
-or sending your device to a third party for testing. Meanwhile, there are no
-required certifications, and thus no corresponding costs and fees.</p></li>
+device manufacturers. The testing tool (CTS) is free, open source, and
+available for <a href="{@docRoot}compatibility/downloads.html">download</a>.
+CTS is designed to be used for continuous self-testing
+during the device development process to eliminate the cost of changing your
+workflow or sending your device to a third party for testing. Meanwhile, there
+are no required certifications, and thus no corresponding costs and
+fees.</p></li>
</ul>
<p>The Android compatibility program consists of three key components:</p>
<ul>
@@ -76,8 +78,9 @@
simply examine <a href="">the latest CDD</a>.</p>
<h3>Compatibility Test Suite (CTS)</h3>
-<p>The CTS is a free, commercial-grade test suite, available along with the
-Android source code. The CTS represents the "mechanism" of compatibility.</p>
+<p>The CTS is a free, commercial-grade test suite, available for
+<a href="{@docRoot}compatibility/downloads.html">download</a>.
+The CTS represents the "mechanism" of compatibility.</p>
<p>The CTS runs on a desktop machine and executes test cases directly on
attached devices or an emulator. The CTS is a set of unit tests designed to be
integrated into the daily workflow (such as via a continuous build system) of
diff --git a/pdk/docs/downloads/downloads_toc.cs b/pdk/docs/downloads/downloads_toc.cs
deleted file mode 100644
index 28f43af..0000000
--- a/pdk/docs/downloads/downloads_toc.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-<script type="text/javascript" language="JavaScript">
-<!--
-function nothing() {}
--->
-</script>
-
-<ul>
- <li><h2>PDK</h2><ul>
- <li><a href="">PDK 1.6</a></li>
- </ul></li>
-
- <li><h2>Compatibility</h2><ul>
- <li><a href="">Android 1.6</a></li>
- </ul></li>
-</ul>
-
-<script type="text/javascript">
-<!--
- buildToggleLists();
-//-->
-</script>
diff --git a/pdk/docs/downloads/index.jd b/pdk/docs/downloads/index.jd
deleted file mode 100644
index b6f5a2f..0000000
--- a/pdk/docs/downloads/index.jd
+++ /dev/null
@@ -1,44 +0,0 @@
-page.title=Downloads
-doc.type=downloads
-doc.hidenav=true
-@jd:body
-<p>This page provides access to various downloads. Note that if you're looking
-for the Android SDK (for application developers), you should visit <a
-href="http://developer.android.com/sdk/index.html">developer.android.com</a>.</p>
-
-<h2>Compatibility</h2>
-<p>The Compatibility Definition Document can be downloaded below. The
-Compatibility Test Suite is available in the open-source tree.</p>
-<table class="download">
- <tr>
- <th>Item</th>
- <th>File</th>
- <th>Size</th>
- </tr>
- <tr>
- <td>Android CDD 2.1</td>
- <td><a href="">android-cdd-2.1.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
- <tr class="alt-color">
- <td>Android CTS 2.1 Manual</td>
- <td><a href="">android-cts-manual-2.1.0.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
- <tr>
- <td>Android CDD 1.6</td>
- <td><a href="">android-cdd-1.6.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
- <tr class="alt-color">
- <td>Android CTS 1.6 Manual</td>
- <td><a href="">android-cts-manual-1.6.4.pdf</a></td>
- <td>23070805 bytes</td>
- </tr>
-</table>
-<p>For more information on how to build an Android-compatible device, see the
-<a href="{@docRoot}compatibility/index.html">Compatibility</a> page. Note that
-there is no compatibility program for Android 1.5 and earlier. Note also that
-there is no compatibility program for Android 2.0, since it was superceded by
-Android 2.1 after only a few weeks.
-</p>
diff --git a/pdk/docs/faqs.jd b/pdk/docs/faqs.jd
index a55d380..00db026 100644
--- a/pdk/docs/faqs.jd
+++ b/pdk/docs/faqs.jd
@@ -74,8 +74,8 @@
<p>Finally, Google works on the next version of the Android platform in tandem
with developing a flagship device. This branch pulls in changes from the
experimental and stable branches as appropriate.</p>
-<p>You can find more information on this topic at our Branches Releases
- page.</p>
+<p>You can find more information on this topic at our <a
+href="{@docRoot}source/code-lines.html">Branches and Releases</a> page.</p>
<h3>Why are parts of Android developed in private?</h3>
<p>It typically takes over a year to bring a device to market, but of course
@@ -86,16 +86,16 @@
<p>To address this, some parts of the next version of Android including the
core platform APIs are developed in a private branch. These APIs constitute
the next version of Android. Our aim is to focus attention on the current
- stable version of the Android source code, while we refine the next version
- of the platform using the flagship Android devices. This allows developers
+ stable version of the Android source code, while we create the next version
+ of the platform as driven by flagship Android devices. This allows developers
and OEMs to focus on a single version without having to track unfinished
- future work just to keep up.Other parts of the Android system that aren't
+ future work just to keep up. Other parts of the Android system that aren't
related to application compatibility are developed in the open, however.
It's our intention to move more of these parts to open development over
time.</p>
<h3>When are source code releases made?</h3>
-<p>When they are ready. Some parts of Android are developed in the open, and
+<p>When they are ready. Some parts of Android are developed in the open,
so that source code is always available. Other parts are developed first in
a private tree, and that source code is released when the next platform
version is ready.</p>
@@ -143,8 +143,7 @@
"Android compatible devices" from devices that merely run derivatives of the
source code. We welcome all uses of the Android source code, but only
Android compatible devices -- as defined and tested by the Android
- Compatibility Program -- may call themselves "Android" and participate in
- the Android ecosystem.</p>
+ Compatibility Program -- may participate in the Android ecosystem.</p>
<h3>How can I contribute to Android?</h3>
<p>There are a number of ways you can contribute to Android. You can report
@@ -170,8 +169,9 @@
<p>Once submitted, changes need to be accepted by a designated Approver.
Approvers are typically Google employees, but the same approvers are
responsible for all submissions, regardless of origin.</p>
-<p>You can find more information on this topic at the Submitting Patches
- page.</p>
+<p>You can find more information on this topic at the <a
+ href="{@docRoot}source/submit-patches.html">Submitting Patches</a>
+ page.</p>
<a name="compatibility"></a><h2>Compatibility</h2>
<h3>What does "compatibility" mean?</h3>
@@ -185,7 +185,7 @@
<p>In other words, compatibility is a prerequisite to participate in the
Android apps ecosystem. Anyone is welcome to use the Android source code,
but if the device isn't compatible, it's not considered part of the Android
- ecosystem, and irrelevant to developers.</p>
+ ecosystem.</p>
<h3>What is the role of Android Market in compatibility?</h3>
<p>Devices that are Android compatible may seek to license the Android Market
@@ -200,11 +200,11 @@
Compatibility Definition Document (CDD) spells out the specific device
configurations that will be considered compatible.</p>
<p>For example, though the Android source code could be ported to run on a
- device that doesn't have a camera, the CDD requires that in order to be
- compatible, all devices must have a camera. This allows developers to rely
- on a consistent set of device capabilities when writing their apps.</p>
+ phone that doesn't have a camera, the CDD requires that in order to be
+ compatible, all phones must have a camera. This allows developers to rely
+ on a consistent set of capabilities when writing their apps.</p>
<p>The CDD will evolve over time to reflect market realities. For instance,
- the 1.6 CDD only allows cell phones, but the 2.x CDD allows devices to omit
+ the 1.6 CDD only allows cell phones, but the 2.1 CDD allows devices to omit
telephony hardware, allowing for non-phone devices such as tablet-style
music players to be compatible. As we make these changes, we will also
augment Android Market to allow developers to retain control over where
@@ -214,13 +214,10 @@
devices.</p>
<h3>If my device is compatible, does it automatically have access to Android Market and branding?</h3>
-<p>Android Market is a service operated by Google. For legal and business
- reasons, Google isn't able to make that service available in all parts of
- the world. Similarly, Google is unable to license the Android trademark for
- use in all cases.</p>
-<p>As a result, achieving compatibility does not automatically entitle a
- device to include Android Market or use the Android name. Device
- manufacturers should contact Google to obtain access to those tools.</p>
+<p>Android Market is a service operated by Google. Achieving compatibility is
+ a prerequisite for obtaining access to the Android Market software and branding.
+ Device manufacturers should contact Google to obtain access to Android
+ Market.</p>
<h3>If I am not a manufacturer, how can I get Android Market?</h3>
<p>Android Market is only licensed to handset manufacturers shipping devices.
@@ -229,9 +226,9 @@
<h3>How can I get access to the Google apps for Android, such as Maps?</h3>
<p>The Google apps for Android, such as YouTube, Google Maps and Navigation,
- Gmail, and so on are not part of Android, and are licensed separately.
- Contact android-partnerships@google.com for inquiries related to those
- apps.</p>
+ Gmail, and so on are Google properties that are not part of Android, and
+ are licensed separately. Contact android-partnerships@google.com for
+ inquiries related to those apps.</p>
<h3>Is compatibility mandatory?</h3>
<p>No. The Android Compatibility Program is optional. Since the Android source
@@ -246,7 +243,7 @@
test a device.</p>
<h3>How long does compatibility take?</h3>
-<p>The process is automatic. The Compatibility Test Suite generates a report
+<p>The process is automated. The Compatibility Test Suite generates a report
that can be provided to Google to verify compatibility. Eventually we intend
to provide self-service tools to upload these reports to a public database.</p>
@@ -271,12 +268,15 @@
generally have much effect on third-party apps. As such, device builders are
free to customize the user interface as much as they like. The Compatibility
Definition Document does restrict the degree to which OEMs may alter the
- system user interface for the few areas that do impact third-party apps.</p>
+ system user interface for areas that do impact third-party apps.</p>
<h3>When are compatibility definitions released for new Android versions?</h3>
<p>Our goal is to release new versions of Android Compatibility Definition
Documents (CDDs) once the corresponding Android platform version has
- converged enough to permit it. Since the CDDs</p>
+ converged enough to permit it. While we can't release a final draft of a CDD
+ for an Android software version before the first flagship device ships with
+ that software, final CDDs will always be released after the first device.
+ However, wherever practical we will make draft versions of CDDs available.</p>
<h3>How are device manufacturers' compatibility claims validated?</h3>
<p>There is no validation process for Android device compatibility. However,
diff --git a/pdk/docs/images/code-lines.png b/pdk/docs/images/code-lines.png
index acfb77b..f86260c 100644
--- a/pdk/docs/images/code-lines.png
+++ b/pdk/docs/images/code-lines.png
Binary files differ
diff --git a/pdk/docs/index.jd b/pdk/docs/index.jd
index 217877d..d8f1739 100644
--- a/pdk/docs/index.jd
+++ b/pdk/docs/index.jd
@@ -1,7 +1,27 @@
page.title=Welcome to Android
home=true
@jd:body
-<div style="float: left; width: 45%; font-size: 1.3em;">
+<div style="float: right; width: 35%;">
+<h3 style="padding-top: 0px;">News</h3>
+<p><b>Compatibility Definition for Android 2.3</b><br/>
+The Compatibility Definition Document for Android 2.3 has been published.
+The 2.3 CDD allows device manufacturers to use the Android source code to ship
+a significantly wider variety of devices, including devices with extra-large
+screens, such as tablets. A release of the Compatibility Test Suite is not
+yet available, but will be soon. For more information, <a
+href="{@docRoot}compatibility/index.html">visit the Compatibility page.</a>
+</p>
+<p><b>Source Code Available for Android 2.3</b><br/>
+The source code for the Android 2.3 platform and software stack has been
+released! This release allows OEMs to begin preparing Android 2.3 for
+installation on new and existing devices, and allows hobbyists, enthusiasts,
+and researchers to develop custom builds. For information on how to obtain the
+software,
+<a href="{@docRoot}source/download.html">visit our 'Getting the Source' page.</a>
+</p>
+</div>
+<img style="float: right; padding-right: 1.5em;" src="{@docRoot}images/home-bugdroid.png" alt="Android Mascot"/>
+<div style="font-size: 1.3em;">
<p>Here you can find the information and source code you need to build an
Android-compatible device.</p>
<p>Android is an open-source software stack for mobile devices, and a
@@ -12,51 +32,40 @@
created Android, and made its source code open.</p>
<p><a href="{@docRoot}about/index.html">Learn more »</a></p>
</div>
-<div style="float: right; width: 35%;">
-<h3 style="padding-top: 0px;">News</h3>
-<p><b>Site redesign</b><br/>
-You're looking at the new and improved source.android.com! We've updated
-the layout and site design, and also added new information. We hope you find
-these improvements helpful.</p>
-<p><b>Introducing the Compatibility Program</b><br/>
-We're pleased to introduce the Android Compatibility Program. We've released
-two tools -- the Compatibility Definition Document and the Compatibility Test
-Suite -- to help device manufacturers build compatible devices. Full details
-of the Compatibility Program will be available in the first quarter of 2010.</p>
-</div>
-<img style="float: right; padding-right: 1.5em;" src="{@docRoot}images/home-bugdroid.png" alt="Android Mascot"/>
<div style="clear: both;"/>
<table border="0" style="border: 0px; margin: 0px; padding: 0px;"><tr><td align="center" style="border: 0px; margin: 0px; padding: 0px;">
<div class="rebox lil" style="float: left; width: 30%; margin: 1em;">
- <h2 style="color: white; background-color: #95C0D0; border: 0px;">Get Involved</h2>
+ <h2 style="color: white; background-color: #95C0D0; border: 0px;">Source</h2>
<div class="p">
- <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
+ <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
If you're interested in contributing to the Android source code or helping
- out with the project in some other way, click here.</p>
- <p><a href="{@docRoot}source/index.html">More »</a></p>
+ out with the open-source project, our Source pages have the information
+ you need.</p>
+ <p><a href="{@docRoot}source/index.html">Get Involved »</a></p>
</div>
</div>
<div class="rebox lil" style="float: left; width: 30%; margin: 1em;">
- <h2 style="color: white; background-color: #95C0D0; border: 0px;">Build a Device</h2>
+ <h2 style="color: white; background-color: #95C0D0; border: 0px;">Porting</h2>
<div class="p">
- <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
- If you're an engineer building a device intended to run the Android
- software stack, click here to find porting information and tips.</p>
- <p><a href="{@docRoot}porting/index.html">More »</a></p>
+ <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
+ If you're an engineer building a device
+ intended to run the Android software stack, look at our Porting pages for
+ information and tips.</p>
+ <p><a href="{@docRoot}porting/index.html">Build a Device »</a></p>
</div>
</div>
<div class="rebox lil" style="float: left; width: 30%; margin: 1em;">
<h2 style="color: white; background-color: #95C0D0; border: 0px;">Compatibility</h2>
<div class="p">
- <p><img src="images/lil-wrench.png" alt="" style="margin: 1em;"/>
- If you're an OEM or other organization building an Android device, click
- here to find out how to ensure that your device is fully compatible, and
- how to take advantage of the benefits of compatibility.</p>
- <p><a href="{@docRoot}compatibility/index.html">More »</a></p>
+ <p><img src="images/lil-wrench.png" alt="" style="margin: 1em; margin-bottom: 5em;"/>
+ If you're an organization building an Android device, you'll want to check out our
+ Compatibility pages to find out how to take advantage of the benefits of
+ compatibility.</p>
+ <p><a href="{@docRoot}compatibility/index.html">Get Compatible »</a></p>
</div>
</div>
</td></tr></table>
diff --git a/pdk/docs/porting/bluetooth.jd b/pdk/docs/porting/bluetooth.jd
index ceb8683..c792bd2 100755
--- a/pdk/docs/porting/bluetooth.jd
+++ b/pdk/docs/porting/bluetooth.jd
@@ -17,7 +17,8 @@
</div>
</div>
-<p>Android's Bluetooth stack uses BlueZ version 3.36 for GAP, SDP, and RFCOMM profiles, and is a SIG-qualified Bluetooth 2.0 + EDR host stack.</p>
+<p>Android's Bluetooth stack uses BlueZ for GAP, SDP, and RFCOMM profiles, and
+is a SIG-qualified Bluetooth stack. </p>
<p>Bluez is GPL licensed, so the Android framework interacts with userspace bluez code through D-BUS IPC to avoid proprietary code.</p>
@@ -33,7 +34,7 @@
<a name="androidBluetoothPorting"></a><h3>Porting</h3>
-<p>BlueZ is Bluetooth 2.0 compatible and should work with any 2.0 chipset. There are two integration points:</p>
+<p>BlueZ is Bluetooth 2.1 compatible and should work with any 2.1 chipset and is backward compatibile with older Bluetooth versions. There are two integration points:</p>
<p><ul>
<li>UART driver</li>
<li>Bluetooth Power On / Off</li>
@@ -67,7 +68,7 @@
<a name="androidBluetoothTroubleshooting"></a><h3>Troubleshooting</h3>
<p><strong>Debugging</strong></p>
-<p>To debug your bluetooth implementation, start by reading the logs (<code>adb logcat</code>) and look for ERRROR and WARNING messages regarding Bluetooth.
+<p>To debug your bluetooth implementation, start by reading the logs (<code>adb logcat</code>) and look for ERRROR and WARNING messages regarding Bluetooth.
Andoird uses Bluez, which comes with some useful debugging tools. The snippet below provides examples in a suggested order:</p>
<pre>
hciconfig -a # print BT chipset address and features. Useful to check if you can communicate with your BT chipset.
@@ -158,14 +159,79 @@
<li>QDID B015261: Host stack (SDP, L2CAP, GAP, RFCOMM, SPP, AVCTP, AVRCP, GAVDP, AVDTP, A2DP)</li>
<li>QDID B015262: EPL for HTC Sapphire (HSP, HFP)</li>
</ul>
+<h4>Android 2.0/2.1 release (eclair)</h4>
+<h4>Platform features</h4>
+<ul>
+ <li>Based on Bluez 4.47 with Linux Kernel 2.6.29</li>
+ <li>Bluetooth 2.1+EDR host stack</li>
+ <ul>
+ <li>Support for auto-pairing with '0000' devices</li>
+ <li>Support for Simple Secure Pairing</li>
+ </ul>
+ <li>Headset Profile 1.1 in Audio Gateway role</li>
+ <li>Handsfree Profile 1.5 in Audio Gateway role</li>
+ <ul>
+ <li>Three-way calling </li>
+ <li>Phonebook over AT commands </li>
+ <li>Volume synchronization</li>
+ <li>eSCO</li>
+ <li>Extensive bug fixes and compatibility improvements</li>
+ </ul>
+ <li>Stereo Bluetooth (A2DP 1.2) in Source role</li>
+ <ul>
+ <li>AVDTP 1.2 in Acceptor and Initiator roles</li>
+ <li>GAVDTP 1.0 in Acceptor and Initiator roles</li>
+ <li>44.1 khz, stereo, software SBC codec</li>
+ </ul>
+ <li>Remote Control (AVRCP 1.0) in Target role</li>
+ <ul>
+ <li>AVCTP 1.3 in Target role</li>
+ <li>play/pause/stop/prev/next</li>
+ </ul>
+ <li> Object Push Profile version 1.1 </li>
+ <ul>
+ <li>Adds ability to transfer pictures, videos</li>
+ <li>Transfer of contacts using vCard is not supported in this release.</li>
+ </ul>
+ <li>Phone Book Address Profile version 1.0</li>
+ <ul>
+ <li>Phone Book Server Equipment (PSE) role supported</li>
+ </ul>
+ <li>Using Java Bluetooth APIs, an Android application can peform the
+ following:</li>
+ <ul>
+ <li>Scan for other Bluetooth devices </li>
+ <li>Query the local Bluetooth adapter for paired Bluetooth devices </li>
+ <li>Establish RFCOMM channels </li>
+ <li>Connect to other devices through service discovery </li>
+ <li>Transfer data to and from other devices </li>
+ <li>Manage multiple connections </li>
+ </ul>
+ <li>Support for Bluetooth enabled car and desk docks</li>
+ <ul>
+ <li>Framework support for routing Phone Call Audio and A2DP streaming using
+ car and desk docks. </li>
+ </ul>
+</ul>
+
+<h4>Android 2.2 release (Froyo)</h4>
+<h4>Platform features</h4>
+<ul>
+ <li>Based on Bluez 4.47 with Linux Kernel 2.6.32</li>
+ <li>No new profiles added.</li>
+ <li>Added ability to share contacts using vCard</li>
+ <li>Added ability to export all contacts - useful to transfer contacts to car kits </li>
+ <li>Improved compatibility with headsets and car kits. </li>
+</ul>
+
<h5> </h5>
<h4>Future releases</h4>
<p>This section offers a rough guide of which features the team is developing for the next release. This feature list may change without notice. It isn't possible to post scheduling advice to the mailing lists.</p>
<ul>
- <li>Java Bluetooth API</li>
- <li>Bluez 4.x with Linux Kernel 2.6.29</li>
<li>More profiles...</li>
- <li>Bluetooth 2.1+EDR</li>
+ <li>Improved compatibility with headsets and car kits</li>
+ <li>Bluetooth emulator support</li>
+ <li>Bluetooth Low Energy </li>
</ul>
<p><strong>Development Notes</strong></p>
@@ -184,10 +250,4 @@
While not officially supported, you should be able to run <code>dund</code> or <code>pand</code> daemons and, using <code>pppd</code> or <code>iptables</code>, test tethering support. Next steps include plubming the DBUS APIs to these daemons up into the Android Java framework and adding code to setup the network paths via <code>pppd</code> and / or <code>iptables</code>.<br />
<br />
</li>
- <li><strong>Emulator Support</strong><br />
- The Android emulator does not support Bluetooth at this time and there currently aren't any plans for its support.<br />
- <br />
- </li>
- <li><strong>Bluetooth 2.1 and Simple Pairing Support</strong><br />
- In order to support these features, Android needs to move to a Bluez 4.x version. This change is not scheduled at this time.</li>
</ul>
diff --git a/pdk/docs/porting/instrumentation_testing.jd b/pdk/docs/porting/instrumentation_testing.jd
index c3765f4..045291f 100755
--- a/pdk/docs/porting/instrumentation_testing.jd
+++ b/pdk/docs/porting/instrumentation_testing.jd
@@ -335,7 +335,7 @@
<pre class="prettify">
public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner {
- @Override
+ @Override
public TestSuite getAllTests() {
InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
@@ -345,7 +345,7 @@
return suite;
}
- @Override
+ @Override
public ClassLoader getLoader() {
return FrameworkInstrumentationTestRunner.class.getClassLoader();
}
@@ -373,7 +373,7 @@
super("com.example", MyActivity.class);
}
- @Override
+ @Override
public void setUp() throws Exception {
super.setUp();
mLeftButton = (Button) getActivity().findViewById(R.id.leftButton);
diff --git a/pdk/docs/source/building-dream.jd b/pdk/docs/source/building-dream.jd
index 89392fd..d130524 100644
--- a/pdk/docs/source/building-dream.jd
+++ b/pdk/docs/source/building-dream.jd
@@ -3,10 +3,10 @@
@jd:body
<p><i>The information on this page is a bit out of date. We'll update this
page as soon as we can.</i></p>
-<div>The basic manifest for cupcake (and above) defines which projects are
+<div>The basic manifest for 1.6 defines which projects are
needed to do a generic build for the emulator or for unlocked Dream devices
(e.g. the Android Dev Phone 1). You need to have an appropriate device running
-a matching official image.<br><br>To build donut or master for dream (your
+a matching official image.<br><br>To build donut for dream (your
device needs to be an ADP1 running an official 1.6 system):<br><ol><li>Follow
the <a href="{@docRoot}source/download.html">normal steps</a>
to setup repo and check out the sources.
@@ -22,17 +22,6 @@
</li>
<li>from this point, the fastboot tool (which is put automatically in your path) can be used to flash a device: boot the device into the bootloader by holding the back key while pressing the power key, and run "fastboot -w flashall".<br></li>
</ol>
-To build cupcake for dream (your device needs to be an ADP1 running an official 1.5 system):<br><ol><li>Follow the <a href="{@docRoot}source/download.html">normal steps</a>
-to setup repo and check out the sources.
-</li>
-<li>At the root of your source tree, run ". build/envsetup.sh" like you normally would for an emulator build.
-</li>
-<li>Run "make adb" if you don't already have adb in your path.<br></li>
-<li>in vendor/htc/dream-open/ there is a script called "extract-files.sh" that must be run (from that directory) to extract some proprietary binaries from your device (*). You only need to do this once.<br></li>
-<li>run "lunch htc_dream-eng" to specifically configure the build system for dream (the default is the equivalent of "lunch generic-eng", which doesn't contain dream-specific files).<br></li>
-<li>run make from the top of the source tree.
-</li>
-<li>from this point, the fastboot tool (which is put automatically in your path) can be used to flash a device: boot the device into the bootloader by holding the back key while pressing the power key, and run "fastboot -w flashall".<br></li>
-</ol>
-* The Dream device software contains some proprietary binaries.For contractual reasons, these cannot be redistributed to be used directly with the Android Open-Source Project, but the provided script may be used to extract these binaries from your development device so that they can be correctly included in your build.These libraries include the openGL|ES library, the Qualcomm camera library, the HTC Radio Interface Library, etc.
+<p>Note: these instructions work for the sapphire (ADP2) build target, as
+well. Simply replace "dream" with "sapphire" above.</p>
</div>
diff --git a/pdk/docs/source/code-lines.jd b/pdk/docs/source/code-lines.jd
index 61b400d..5ceb103 100644
--- a/pdk/docs/source/code-lines.jd
+++ b/pdk/docs/source/code-lines.jd
@@ -15,7 +15,7 @@
<h3>Notes and Explanations</h3>
<ul>
<li>A <i>release</i> corresponds to a formal version of the Android platform, such
-as 1.5, 2.0, and so on. Generally speaking, a release of the platform
+as 1.5, 2.1, and so on. Generally speaking, a release of the platform
corresponds to a version of the <code>SdkVersion</code> field used in
AndroidManifest.xml files, and defined in <code>frameworks/base/api</code> in
the source tree.</li>
@@ -23,34 +23,37 @@
stack is pulling code. These include obvious projects such as the Linux kernel
and WebKit, but over time we are migrating some of the semi-autonomous
Android projects (such as Dalvik, the Android SDK tools, Bionic, and so on) to
-work as "upstream" projects. These will be developed entirely in the public
-tree, and snapshots will be periodically pulled into releases.</li>
-<li>The diagram refers to "Eclair" and "Flan"; however, they are simply
+work as "upstream" projects. Generally, these projects are developed entirely in
+the public tree. For some upstream projects, development is done by contributing
+directly to the upstream project itself. See
+<a href="{@docRoot}source/submit-patches.html#upstream-projects">Upstream Projects</a>
+for details. In both cases, snapshots will be periodically pulled into releases.</li>
+<li>The diagram refers to "Eclair" and "FroYo"; however, they are simply
placeholders, and the diagram actually reflects the overall release and
branching strategy.</li>
-<li>At all times, the Release code-line (which may actually consist of
+<li>At all times, a release code-line (which may actually consist of
more than one actual branch in git) is considered the sole canonical source
-code for a given Android platform. OEMs and other groups building devices
-should pull only from a Release branch.</li>
-<li>We will be setting up an "Experimental" code-line to capture changes from
+code for a given Android platform version. OEMs and other groups building devices
+should pull only from a release branch.</li>
+<li>We will set up "experimental" code-lines to capture changes from
the community, so that they can be iterated on, with an eye toward stability.</li>
-<li>Changes that prove stable will eventually be pulled into a Release
+<li>Changes that prove stable will eventually be pulled into a release
branch. Note that this will only apply to bug fixes, app improvements, and
other things that do not affect the APIs of the platform.</li>
-<li>Changes will be pulled into Release branches from upstream projects
-(include the Android "upstream" projects) as necessary.</li>
+<li>Changes will be pulled into release branches from upstream projects
+(including the Android "upstream" projects) as necessary.</li>
<li>The "n+1"th version (that is, next major version of the framework and
-platform APIs) will be developed by Google internally. (See below for
-details.)</li>
-<li>Changes will be pulled from upstream, Release, and Experimental branches
+platform APIs) will be developed by Google internally. See below for
+details.</li>
+<li>Changes will be pulled from upstream, release, and experimental branches
into Google's private branch as necessary.</li>
<li>When the platform APIs for the next version have stabilized and been fully
tested, Google will cut a release of the next platform version. (This
specifically refers to a new <code>SdkVersion</code>.) This will also
-correspond to the internal code-line being made a public Release branch, and the
+correspond to the internal code-line being made a public release branch, and the
new current platform code-line.</li>
-<li>When a new platform version is cut, a corresponding Experimental
-code-line.</li>
+<li>When a new platform version is cut, a corresponding experimental
+code-line will be created at the same time.</li>
</ul>
<h3>About Private Code-Lines</h3>
<p>The source management strategy above includes a code-line that Google will
@@ -62,9 +65,9 @@
Google retains responsibility for the strategic direction of Android as a
platform and a product. Our approach is based on focusing on a small number of
flagship devices to drive features, and secure protections of Android-related
-intellectual property through patents and the like.</p>
+intellectual property.</p>
<p>As a result, Google frequently has possession of confidential
-information of third parties, and we must refrain from revealing patentable
+information of third parties, and we must refrain from revealing sensitive
features until we've secured the appropriate protections. Meanwhile, there are
real risks to the platform arising from having too many platform versions
extant at once. For these reasons, we have structured the open-source project
diff --git a/pdk/docs/source/code-style.jd b/pdk/docs/source/code-style.jd
index 8b5946e..957ab02 100644
--- a/pdk/docs/source/code-style.jd
+++ b/pdk/docs/source/code-style.jd
@@ -1,7 +1,6 @@
page.title=Code Style Guidelines for Contributors
doc.type=source
@jd:body
-<div>
<p>The rules below are not guidelines or recommendations, but strict rules.
Contributions to Android generally <b>will not be accepted if they do not
adhere to these rules.</b>
@@ -11,425 +10,615 @@
</h1>
<p>We follow standard Java coding conventions. We add a few rules:
</p>
-<ol><li><a href="#exceptionsIgnore">Exceptions</a>
-: Never catch and ignore them without explanation.
-</li>
-<li><a href="#exceptionsAll">Exceptions</a>
-: do not catch generic Exception, except in library code at the root of the stack.
-</li>
-<li><a href="#finalizers">Finalizers</a>
-: generally don't use them.
-</li>
-<li><a href="#imports">Imports</a>
-: Fully qualify imports
-</li>
+<ol><li><a href="#exceptionsIgnore">Exceptions</a>: Never catch and ignore them without explanation.</li>
+<li><a href="#exceptionsAll">Exceptions</a>: do not catch generic Exception, except in library code at the root of the stack.</li>
+<li><a href="#finalizers">Finalizers</a>: generally don't use them.</li>
+<li><a href="#imports">Imports</a>: Fully qualify imports</li>
</ol>
-<h1><a>Java Library Rules</a>
-</h1>
-<p>There are conventions for using Android's Java libraries and tools. In some cases, the convention has changed in important ways and older code might use a deprecated pattern or library. When working with such code, it's okay to continue the existing style (see <a href="#consistency">Consistency</a>
-). When creating new components never use deprecated libraries.
-</p>
-<h1><a>Java Style Rules</a>
-</h1>
-<p>Programs are much easier to maintain when all files have a consistent style. We follow the standard Java coding style, as defined by Sun in their <a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Code Conventions for the Java Programming Language</a>
-, with a few exceptions and additions. This style guide is comprehensive and detailed and is in common usage in the Java community.
-</p>
-<p>In addition, we enforce the following style rules:
-</p>
-<ol><li><a href="#javadoc">Comments/Javadoc</a>
-: write it; use standard style
-</li>
-<li><a href="#shortmethods">Short methods</a>
-: don't write giant methods
-</li>
-<li>Fields: should either be at the top of the file, or immediately before the methods that use them
-</li>
-<li><a href="#localvariables">Local variables</a>
-: limit the scope
-</li>
-<li><a href="#import_style">Imports</a>
-: android; third party alphabetical; java(x)
-</li>
-<li><a href="#indentation">Indentation</a>
-: 4 spaces, no tabs.
-</li>
-<li><a href="#linelen">Line length</a>
-: 100 columns
-</li>
-<li><a href="#field_names">Field names</a>
-: Non-public, non-static fields start with m. Static fields start s.
-</li>
-<li><a href="#braces">Braces</a>
-: Opening braces don't go on their own line.
-</li>
-<li><a href="#annotations">Annotations</a>
-: Use the standard annotations.
-</li>
-<li><a href="#acronyms">Acronyms are words</a>
-: Treat acronyms as words in names, yielding XmlHttpRequest, getUrl(), etc.
-</li>
-<li><a href="#todo">TODO style</a>
-: "TODO: write this description"
-</li>
-<li><a href="#consistency">Consistency</a>
-: Look at what's around you!
-</li>
-<li><a href="#logging">Logging</a>
-: Be careful with logging. It's expensive.
-</li>
+<h1>Java Library Rules</h1>
+<p>There are conventions for using Android's Java libraries and tools. In some
+cases, the convention has changed in important ways and older code might use a
+deprecated pattern or library. When working with such code, it's okay to
+continue the existing style (see <a href="#consistency">Consistency</a>). When
+creating new components never use deprecated libraries.</p>
+<h1>Java Style Rules</h1>
+<p>Programs are much easier to maintain when all files have a consistent
+style. We follow the standard Java coding style, as defined by Sun in their <a
+href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Code
+Conventions for the Java Programming Language</a>, with a few exceptions and
+additions. This style guide is comprehensive and detailed and is in common
+usage in the Java community.</p>
+<p>In addition, we enforce the following style rules:</p>
+<ol><li><a href="#javadoc">Comments/Javadoc</a>: write it; use standard style</li>
+<li><a href="#shortmethods">Short methods</a>: don't write giant methods</li>
+<li>Fields: should either be at the top of the file, or immediately before the methods that use them</li>
+<li><a href="#localvariables">Local variables</a>: limit the scope</li>
+<li><a href="#import_style">Imports</a>: android; third party alphabetical; java(x)</li>
+<li><a href="#indentation">Indentation</a>: 4 spaces, no tabs.</li>
+<li><a href="#linelen">Line length</a>: 100 columns</li>
+<li><a href="#field_names">Field names</a>: Non-public, non-static fields start with m.</li>
+<li><a href="#braces">Braces</a>: Opening braces don't go on their own line.</li>
+<li><a href="#annotations">Annotations</a>: Use the standard annotations.</li>
+<li><a href="#acronyms">Acronyms are words</a>: Treat acronyms as words in names, yielding XmlHttpRequest, getUrl(), etc.</li>
+<li><a href="#todo">TODO style</a>: "TODO: write this description"</li>
+<li><a href="#consistency">Consistency</a>: Look at what's around you!</li>
+<li><a href="#logging">Logging</a>: Be careful with logging. It's expensive.</li>
</ol>
-<h1><a>Javatests Style Rules</a>
-</h1>
-<ol><li><a href="#testmethodnames">Naming test methods</a>
-: testMethod_specificCase is ok
-</li>
+<h1>Javatests Style Rules</h1>
+<ol>
+<li><a href="#testmethodnames">Naming test methods</a>: testMethod_specificCase is ok</li>
</ol>
-<hr><h2>
-Java Language Rules
-</h2>
-<h2><a>Exceptions: do not ignore</a>
-</h2>
-Sometimes it is tempting to write code that completely ignores an exception like this:
-<pre>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>}<br>}<br><br></pre>
-<p>You must never do this. While you may think that your code will never encounter this error condition or that it is not important to handle it, ignoring exceptions like above creates mines in your code for someone else to trip over some day. You must handle every Exception in your code in some principled way. The specific handling varies depending on the case.
-</p>
-<blockquote>Anytime somebody has an empty catch clause they should have a creepy feeling. There are definitely times when it is actually the correct thing to do, but at least you have to think about it. In Java you can't escape the creepy feeling.<br><div>-<a href="http://www.artima.com/intv/solid4.html">James Gosling</a>
-</div>
-</blockquote>
-<p>Acceptable alternatives (in order of preference) are:
-</p>
-<ul><li>Throw the exception up to the caller of your method.
-<pre>void setServerPort(String value) throws NumberFormatException {<br>serverPort = Integer.parseInt(value);<br>}<br><br></pre>
-</li>
+<h2>Java Language Rules</h2>
+<h2><a name="exceptionsIgnore"></a>Exceptions: do not ignore</h2>
+<p>Sometimes it is tempting to write code that completely ignores an exception
+like this:</p>
+<pre>void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) { }
+}</pre>
+<p>You must never do this. While you may think that your code will never
+encounter this error condition or that it is not important to handle it,
+ignoring exceptions like above creates mines in your code for someone else to
+trip over some day. You must handle every Exception in your code in some
+principled way. The specific handling varies depending on the case.</p>
+<blockquote>Anytime somebody has an empty catch clause they should have a
+creepy feeling. There are definitely times when it is actually the correct
+thing to do, but at least you have to think about it. In Java you can't escape
+the creepy feeling.
+-<a href="http://www.artima.com/intv/solid4.html">James
+Gosling</a></blockquote>
+<p>Acceptable alternatives (in order of preference) are:</p>
+<ul>
+<li>Throw the exception up to the caller of your method.
+<pre>void setServerPort(String value) throws NumberFormatException {
+ serverPort = Integer.parseInt(value);
+}</pre></li>
<li>Throw a new exception that's appropriate to your level of abstraction.
-<pre>void setServerPort(String value) throws ConfigurationException {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>throw new ConfigurationException("Port " + value + " is not valid.");<br>}<br><br></pre>
-</li>
-<li>Handle the error gracefully and substitute an appropriate value in the catch {} block.
-<pre>/** Set port. If value is not a valid number, 80 is substituted. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>serverPort = 80; // default port for server <br>}<br></pre>
-</li>
-<li>Catch the Exception and throw a new RuntimeException. This is dangerous: only do it if you are positive that if this error occurs, the appropriate thing to do is crash.
-<pre>/** Set port. If value is not a valid number, die. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>throw new RuntimeException("port " + value " is invalid, ", e);<br>}<br></pre>
-Note that the original exception is passed to the constructor for RuntimeException. This wrapped exception paradigm is very useful but only works in Java 1.4. If your code must compile under Java 1.3, you will need to omit the exception that is the cause.<br><br></li>
-<li>Last resort: if you are confident that actually ignoring the exception is appropriate then you may ignore it, but you must also comment why with a good reason:
-<pre>/** If value is not a valid number, original port number is used. */<br>void setServerPort(String value) {<br>try {<br>serverPort = Integer.parseInt(value);<br>} catch (NumberFormatException e) {<br>// Method is documented to just ignore invalid user input.<br>// serverPort will just be unchanged.<br>}<br>}<br></pre>
-</li>
+<pre>void setServerPort(String value) throws ConfigurationException {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new ConfigurationException("Port " + value + " is not valid.");
+ }
+}</pre></li>
+<li>Handle the error gracefully and substitute an appropriate value in the
+catch {} block.
+<pre>/** Set port. If value is not a valid number, 80 is substituted. */
+void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ serverPort = 80; // default port for server
+ }
+}</pre></li>
+<li>Catch the Exception and throw a new RuntimeException. This is dangerous:
+only do it if you are positive that if this error occurs, the appropriate
+thing to do is crash.
+<pre>/** Set port. If value is not a valid number, die. */
+void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ throw new RuntimeException("port " + value " is invalid, ", e);
+ }
+}</pre>
+Note that the original exception is passed to the constructor for
+RuntimeException. If your code must compile under Java 1.3, you will need to
+omit the exception that is the cause.</li>
+<li>Last resort: if you are confident that actually ignoring the exception is
+appropriate then you may ignore it, but you must also comment why with a good
+reason:
+<pre>/** If value is not a valid number, original port number is used. */
+void setServerPort(String value) {
+ try {
+ serverPort = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ // Method is documented to just ignore invalid user input.
+ // serverPort will just be unchanged.
+ }
+}</pre></li>
</ul>
-<h2><a>Exceptions: do not catch generic Exception</a>
-</h2>
-Sometimes it is tempting to be lazy when catching exceptions and do something like this:
-<pre>try {<br>someComplicatedIOFunction(); // may throw IOException <br>someComplicatedParsingFunction(); // may throw ParsingException <br>someComplicatedSecurityFunction(); // may throw SecurityException <br>// phew, made it all the way <br>} catch (Exception e) { // I'll just catch all exceptions <br>handleError(); // with one generic handler!<br>}<br><br></pre>
-You should not do this. In almost all cases it is inappropriate to catch generic Exception or Throwable, preferably not Throwable, because it includes Error exceptions as well. It is very dangerous. It means that Exceptions you never expected (including RuntimeExceptions like ClassCastException) end up getting caught in application-level error handling. It obscures the failure handling properties of your code. It means if someone adds a new type of Exception in the code you're calling, the compiler won't help you realize you need to handle that error differently. And in most cases you shouldn't be handling different types of exception the same way, anyway.
-<p>There are rare exceptions to this rule: certain test code and top-level code where you want to catch all kinds of errors (to prevent them from showing up in a UI, or to keep a batch job running). In that case you may catch generic Exception (or Throwable) and handle the error appropriately. You should think very carefully before doing this, though, and put in comments explaining why it is safe in this place.
-</p>
-<p>Alternatives to catching generic Exception:
-</p>
-<ul><li>Catch each exception separately as separate catch blocks after a single try. This can be awkward but is still preferable to catching all Exceptions. Beware repeating too much code in the catch blocks.
-</li>
-<li>Refactor your code to have more fine-grained error handling, with multiple try blocks. Split up the IO from the parsing, handle errors separately in each case.
-</li>
-<li>Rethrow the exception. Many times you don't need to catch the exception at this level anyway, just let the method throw it.
-</li>
+<h2><a name="exceptionsAll"></a>Exceptions: do not catch generic Exception</h2>
+<p>Sometimes it is tempting to be lazy when catching exceptions and do
+something like this:</p>
+<pre>try {
+ someComplicatedIOFunction(); // may throw IOException
+ someComplicatedParsingFunction(); // may throw ParsingException
+ someComplicatedSecurityFunction(); // may throw SecurityException
+ // phew, made it all the way
+} catch (Exception e) { // I'll just catch all exceptions
+ handleError(); // with one generic handler!
+}</pre>
+<p>You should not do this. In almost all cases it is inappropriate to catch
+generic Exception or Throwable, preferably not Throwable, because it includes
+Error exceptions as well. It is very dangerous. It means that Exceptions you
+never expected (including RuntimeExceptions like ClassCastException) end up
+getting caught in application-level error handling. It obscures the failure
+handling properties of your code. It means if someone adds a new type of
+Exception in the code you're calling, the compiler won't help you realize you
+need to handle that error differently. And in most cases you shouldn't be
+handling different types of exception the same way, anyway.</p>
+<p>There are rare exceptions to this rule: certain test code and top-level
+code where you want to catch all kinds of errors (to prevent them from showing
+up in a UI, or to keep a batch job running). In that case you may catch
+generic Exception (or Throwable) and handle the error appropriately. You
+should think very carefully before doing this, though, and put in comments
+explaining why it is safe in this place.</p>
+<p>Alternatives to catching generic Exception:</p>
+<ul>
+<li>Catch each exception separately as separate catch blocks after a single
+try. This can be awkward but is still preferable to catching all Exceptions.
+Beware repeating too much code in the catch blocks.</li>
+<li>Refactor your code to have more fine-grained error handling, with multiple
+try blocks. Split up the IO from the parsing, handle errors separately in each
+case.</li>
+<li>Rethrow the exception. Many times you don't need to catch the exception at
+this level anyway, just let the method throw it.</li>
</ul>
-Remember: exceptions are your friend! When the compiler complains you're not catching an exception, don't scowl. Smile: the compiler just made it easier for you to catch runtime problems in your code.
-<h2><a>Finalizers</a>
-</h2>
-<p><b>What it is</b>
-: Finalizers are a way to have a chunk of code executed when an object is garbage collected.
-</p>
-<p><b>Pros</b>
-: can be handy for doing cleanup, particularly of external resources.
-</p>
-<p><b>Cons</b>
-: there are no guarantees as to when a finalizer will be called, or even that it will be called at all.
-</p>
-<p><b>Decision</b>
-: we don't use finalizers. In most cases, you can do what you need from a finalizer with good exception handling. If you absolutely need it, define a close() method (or the like) and document exactly when that method needs to be called. See InputStream for an example. In this case it is appropriate but not required to print a short log message from the finalizer, as long as it is not expected to flood the logs.
-</p>
-<p>The one exception is it is OK to write a finalizer if all it does is make calls to X.assertTrue().
-</p>
-<h2><a>Imports</a>
-</h2>
-<h3>
-Wildcards in imports
-</h3>
-<p><b>What it is</b>
-: When you want to use class Bar from package foo,there are two possible ways to import it:
-</p>
-<ol><li>import foo.*;
-</li>
-<li>import foo.Bar;
-</li>
+<p>Remember: exceptions are your friend! When the compiler complains you're
+not catching an exception, don't scowl. Smile: the compiler just made it
+easier for you to catch runtime problems in your code.</p>
+<h2><a name="finalizers"></a>Finalizers</h2>
+<p><b>What it is</b>: Finalizers are a way to have a chunk of code executed
+when an object is garbage collected.</p>
+<p><b>Pros</b>: can be handy for doing cleanup, particularly of external
+resources.</p>
+<p><b>Cons</b>: there are no guarantees as to when a finalizer will be called,
+or even that it will be called at all.</p>
+<p><b>Decision</b>: we don't use finalizers. In most cases, you can do what
+you need from a finalizer with good exception handling. If you absolutely need
+it, define a close() method (or the like) and document exactly when that
+method needs to be called. See InputStream for an example. In this case it is
+appropriate but not required to print a short log message from the finalizer,
+as long as it is not expected to flood the logs.</p>
+<h2><a name="imports"></a>Imports</h2>
+<h3>Wildcards in imports</h3>
+<p><b>What it is</b>: When you want to use class Bar from package foo,there
+are two possible ways to import it:</p>
+<ol>
+<li><code>import foo.*;</code></li>
+<li><code>import foo.Bar;</code></li>
</ol>
-<p><b>Pros of #1</b>
-: Potentially reduces the number of import statements.
+<p><b>Pros of #1</b>: Potentially reduces the number of import statements.
</p>
-<p><b>Pros of #2</b>
-: Makes it obvious what classes are actually used. Makes code more readable for maintainers.
-</p>
-<p><b>Decision</b>
-:Use style #2 for importing all Android code. An explicit exception is made for java standard libraries (java.util.*, java.io.*, etc.) and unit test code (junit.framework.*).
-</p>
-<h2><a>Comments/Javadoc</a>
-</h2>
-<p>Every file should have a copyright statement at the top. Then a package statement and import statements should follow, each block separated by a blank line. And then there is the class or interface declaration. In the Javadoc comments, describe what the class or interface does.
-</p>
-<pre>/*<br>* Copyright (C) 2007 The Android Open Source Project <br>*<br>* Licensed under the Apache License, Version 2.0 (the "License");<br>* you may not use this file except in compliance with the License.<br>* You may obtain a copy of the License at <br>*<br>* http://www.apache.org/licenses/LICENSE-2.0<br>*<br>* Unless required by applicable law or agreed to in writing, software <br>* distributed under the License is distributed on an "AS IS" BASIS,<br>* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br>* See the License for the specific language governing permissions and <br>* limitations under the License.<br>*/<br><br>package com.android.internal.foo;<br><br>import android.os.Blah;<br>import android.view.Yada;<br><br>import java.sql.ResultSet;<br>import java.sql.SQLException;<br><br>/**<br>* Does X and Y and provides an abstraction for Z.<br>*/<br>public class Foo {<br>...<br>}<br></pre>
-<p>Every class and nontrivial public method you write <b>must</b>
-contain a Javadoc comment with at least one sentence describing what the class or method does. This sentence should start with a 3rd person descriptive verb. Examples:
-</p>
-<pre>/** Returns the correctly rounded positive square root of a double value. */<br>static double sqrt(double a) {<br>}<br><br>/**<br>* Constructs a new String by converting the specified array of <br>* bytes using the platform's default character encoding.<br>*/<br>public String(byte[] bytes) {<br>}<br></pre>
-<p>You do not need to write Javadoc for trivial get and set methods such as setFoo() if all your Javadoc would say is "sets Foo". If the method does something more complex (such as enforcing a constraint or having an important side effect), then you must document it. And if it's not obvious what the property "Foo" means, you should document it.
-</p>
-<p>Every method you write, whether public or otherwise, would benefit from Javadoc. Public methods are part of an API and therefore require Javadoc.
-</p>
-Android does not currently enforce a specific style for writing Javadoc comments, but you <b>should</b>
-follow the <a href="http://java.sun.com/j2se/javadoc/writingdoccomments/">Sun Javadoc conventions</a>
-.
-<h2><a>Short methods</a>
-</h2>
-To the extent that it is feasible, methods should be kept small and focused. It is, however, recognized that long methods are sometimes appropriate, so no hard limit is placed on method length. If a method exceeds 40 lines or so, think about whether it can be broken up without harming the structure of the program.
-<h2><a>Local variables</a>
-</h2>
-The scope of local variables should be kept to a minimum (<i>Effective Java</i>
-Item 29). By doing so, you increase the readability and maintainability of your code and reduce the likelihood of error. Each variable should be declared in the innermost block that encloses all uses of the variable.
-<p>Local variables should be declared at the point they are first used. Nearly every local variable declaration should contain an initializer. If you don't yet have enough information to initialize a variable sensibly, you should postpone the declaration until you do.
-</p>
-<p>One exception to this rule concerns try-catch statements. If a variable is initialized with the return value of a method that throws a checked exception, it must be initialized inside a try block. If the value must be used outside of the try block, then it must be declared before the try block, where it cannot yet be sensibly initialized:
-</p>
-<pre>// Instantiate class cl, which represents some sort of Set <br>Set s = null;<br>try {<br>s = (Set) cl.newInstance();<br>} catch(IllegalAccessException e) {<br>throw new IllegalArgumentException(cl + " not accessible");<br>} catch(InstantiationException e) {<br>throw new IllegalArgumentException(cl + " not instantiable");<br>}<br><br>// Exercise the set <br>s.addAll(Arrays.asList(args));<br></pre>
-<p>But even this case can be avoided by encapsulating the try-catch block in a method:
-</p>
-<pre>Set createSet(Class cl) {<br>// Instantiate class cl, which represents some sort of Set <br>try {<br>return (Set) cl.newInstance();<br>} catch(IllegalAccessException e) {<br>throw new IllegalArgumentException(cl + " not accessible");<br>} catch(InstantiationException e) {<br>throw new IllegalArgumentException(cl + " not instantiable");<br>}<br>}<br>...<br>// Exercise the set <br>Set s = createSet(cl);<br>s.addAll(Arrays.asList(args));<br></pre>
-Loop variables should be declared in the for statement itself unless there is a compelling reason to do otherwise:
-<pre>for (int i = 0; i n; i++) {<br>doSomething(i);<br>}<br><br>for (Iterator i = c.iterator(); i.hasNext(); ) {<br>doSomethingElse(i.next());<br>}<br><br><br></pre>
-<h2><a>Imports</a>
-</h2>
-The ordering of import statements is:Android importsImports from third parties (com, junit, net, org)<br>java and javax
-<p>To exactly match the IDE settings, the imports should be:
-</p>
-Alphabetical within each grouping.<br>Capital letters are considered to come before lower case letter (e.g. Z before a).There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).
-<h4>
-Why?
-</h4>
-<p>Originally there was no style requirement on the ordering. This meant that the IDE's were either always changing the ordering, or IDE developers had to disable the automatic import management features and maintain the imports by hand. This was deemed bad. When java-style was asked, the preferred styles were all over the map. It pretty much came down to our needing to "pick an ordering and be consistent." So we chose a style, updated the javaguide and made the IDE's obey it. We expect that as IDE users work on the code, the imports in all of the packages will end up matching this pattern without any extra engineering effort.
-</p>
-<p>The style chosen such that:
-</p>
-The imports people want to look at first tend to be at the top (android)The imports people want to look at least tend to be at the bottom (java)Humans can easily follow the styleThe IDE's can follow the style
-<h3>
-What about static imports?
-</h3>
-The use and location of static imports have been mildly controversial issues. Some people would prefer static imports to be interspersed with the remaining imports, some would prefer them reside above or below all other imports. Additinally, we have not yet come up with a way to make all IDEs use the same ordering.
-<p>Since most people consider this a low priority issue, just use your judgement and please be consistent.
-</p>
+<p><b>Pros of #2</b>: Makes it obvious what classes are actually used. Makes
+code more readable for maintainers. </p>
+<p><b>Decision</b>: Use style #2 for importing all Android code. An explicit
+exception is made for java standard libraries (java.util.*, java.io.*, etc.)
+and unit test code (junit.framework.*).</p>
+<h2><a name="javadoc"></a>Comments/Javadoc</h2>
+<p>Every file should have a copyright statement at the top. Then a package
+statement and import statements should follow, each block separated by a blank
+line. And then there is the class or interface declaration. In the Javadoc
+comments, describe what the class or interface does.</p>
+<pre>/*
+ * Copyright (C) 2010 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.
+ */
-<h2><a>Indentation</a>
-</h2>
-<p>We use 4 space indents for blocks. We never use tabs. When in doubt, be consistent with code around you.
-</p>
-<p>We use 8 space indents for line wraps, including function calls and assignments. For example, this is correct:
-</p>
-<pre>Instrument i <br>= someLongExpression(that, wouldNotFit, on, one, line);</pre>
-and this is not correct:
-<pre>Instrument i <br>= someLongExpression(that, wouldNotFit, on, one, line);</pre>
-<h2><a>Field Names</a>
-</h2>
-<ul><li>Non-public, non-static field names start with m.
-</li>
-<li>Static field names start with s.
-</li>
-<li>Other fields start with a lower case letter.
-</li>
-<li>Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.
-</li>
+package com.android.internal.foo;
+
+import android.os.Blah;
+import android.view.Yada;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Does X and Y and provides an abstraction for Z.
+ */
+public class Foo {
+ ...
+}</pre>
+<p>Every class and nontrivial public method you write <b>must</b> contain a
+Javadoc comment with at least one sentence describing what the class or method
+does. This sentence should start with a 3rd person descriptive verb.
+Examples:</p>
+<pre>/** Returns the correctly rounded positive square root of a double value. */
+static double sqrt(double a) {
+}
+
+/**
+ * Constructs a new String by converting the specified array of
+ * bytes using the platform's default character encoding.
+ */
+public String(byte[] bytes) {
+}</pre>
+<p>You do not need to write Javadoc for trivial get and set methods such as
+setFoo() if all your Javadoc would say is "sets Foo". If the method does
+something more complex (such as enforcing a constraint or having an important
+side effect), then you must document it. And if it's not obvious what the
+property "Foo" means, you should document it.</p>
+<p>Every method you write, whether public or otherwise, would benefit from
+Javadoc. Public methods are part of an API and therefore require Javadoc.</p>
+<p>Android does not currently enforce a specific style for writing Javadoc
+comments, but you <b>should</b> follow the <a
+href="http://java.sun.com/j2se/javadoc/writingdoccomments/">Sun Javadoc
+conventions</a>.</p>
+<h2><a name="shortmethods"></a>Short methods</h2>
+<p>To the extent that it is feasible, methods should be kept small and
+focused. It is, however, recognized that long methods are sometimes
+appropriate, so no hard limit is placed on method length. If a method exceeds
+40 lines or so, think about whether it can be broken up without harming the
+structure of the program.</p>
+<h2><a name="localvariables"></a>Local variables</h2>
+<p>The scope of local variables should be kept to a minimum (<i>Effective
+Java</i> Item 29). By doing so, you increase the readability and
+maintainability of your code and reduce the likelihood of error. Each variable
+should be declared in the innermost block that encloses all uses of the
+variable.</p>
+<p>Local variables should be declared at the point they are first used. Nearly
+every local variable declaration should contain an initializer. If you don't
+yet have enough information to initialize a variable sensibly, you should
+postpone the declaration until you do.</p>
+<p>One exception to this rule concerns try-catch statements. If a variable is
+initialized with the return value of a method that throws a checked exception,
+it must be initialized inside a try block. If the value must be used outside
+of the try block, then it must be declared before the try block, where it
+cannot yet be sensibly initialized:</p>
+<pre>// Instantiate class cl, which represents some sort of Set
+Set s = null;
+try {
+ s = (Set) cl.newInstance();
+} catch(IllegalAccessException e) {
+ throw new IllegalArgumentException(cl + " not accessible");
+} catch(InstantiationException e) {
+ throw new IllegalArgumentException(cl + " not instantiable");
+}
+
+// Exercise the set
+s.addAll(Arrays.asList(args));</pre>
+<p>But even this case can be avoided by encapsulating the try-catch block in a method:</p>
+<pre>Set createSet(Class cl) {
+ // Instantiate class cl, which represents some sort of Set
+ try {
+ return (Set) cl.newInstance();
+ } catch(IllegalAccessException e) {
+ throw new IllegalArgumentException(cl + " not accessible");
+ } catch(InstantiationException e) {
+ throw new IllegalArgumentException(cl + " not instantiable");
+ }
+}
+
+...
+
+// Exercise the set
+Set s = createSet(cl);
+s.addAll(Arrays.asList(args));</pre>
+<p>Loop variables should be declared in the for statement itself unless there
+is a compelling reason to do otherwise:</p>
+<pre>for (int i = 0; i n; i++) {
+ doSomething(i);
+}
+
+for (Iterator i = c.iterator(); i.hasNext(); ) {
+ doSomethingElse(i.next());
+}</pre>
+<h2><a name="import_style"></a>Imports</h2>
+<p>The ordering of import statements is:</p>
+<ol>
+<li>Android imports</li>
+<li>Imports from third parties (com, junit, net, org)</li>
+<li>java and javax</li>
+</ol>
+<p>To exactly match the IDE settings, the imports should be:</p>
+<ul>
+<li>Alphabetical within each grouping.</li>
+<li>Capital letters are considered to come before lower case letter (e.g. Z before a).</li>
+<li>There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).</li>
</ul>
-<p>For example:
-</p>
-<pre>public class MyClass {<br>public static final int SOME_CONSTANT = 42;<br>public int publicField;<br>private static MyClass sSingleton;<br>int mPackagePrivate;<br>private int mPrivate;<br>protected int mProtected;<br>}</pre>
-<h2><a>Braces</a>
-</h2>
-<p>Braces do not go on their own line; they go on the same line as the code before them. So:
-</p>
-<pre>class MyClass {<br>int func() {<br>if (something) {<br>// ...<br>} else if (somethingElse) {<br>// ...<br>} else {<br>// ...<br>}<br>}<br>}<br></pre>
-<p>We require braces around the statements for a conditional. Except, if the entire conditional (the condition and the body) fit on one line, you may (but are not obligated to) put it all on one line. That is, this is legal:
-</p>
-<pre>if (condition) {<br>body; // ok <br>}<br>if (condition) body; // ok</pre>
-<p>but this is still illegal:
-</p>
-<pre>if (condition)<br>body; // bad <br></pre>
-<h2><a>Line length</a>
-</h2>
-<p>Each line of text in your code should be at most 100 characters long.
-</p>
-<p>There has been lots of discussion about this rule and the decision remains that 100 characters is the maximum.
-</p>
-<p>Exception: if a comment line contains an example command or a literal URL longer than 100 characters, that line may be longer than 100 characters for ease of cut and paste.
-</p>
-<p>Exception: import lines can go over the limit because humans rarely see them. This also simplifies tool writing.
-</p>
-<h2>
-Java 1.5 Annotations
-</h2>
-<p>Annotations should precede other modifiers for the same language element. Simple marker annotations (e.g. @Override) can be listed on the same line with the language element. If there are multiple annotations, or parameterized annotations, they should each be listed one-per-line in alphabetical order.
-</p>
-<p>Android -standard practices for the three predefined annotations in Java 1.5's are:
-</p>
-@DeprecatedThe @Deprecated annotation must be used whenever the use of the annotated element is discouraged. If you use the @Deprecated annotation, you must also have a @deprecated Javadoc tag and it should name an alternate implementation. In addition, remember that a @Deprecated method is <b>still</b>
-supposed to work.
-<p>If you see old code that has a @deprecated Javadoc tag, please add the @Deprecated annotation.
-</p>
-@OverrideThe @Override annotation must be used whenever a method overrides the declaration or implementation from a super-class.
-<p>For example, if you use the {@inheritdocs} Javadoc tag, and derive from a class (not an interface), you must also annotate that the method @Overrides the parent class's method.
-</p>
-@SuppressWarningsThe @SuppressWarnings annotation should only be used under circumstances where it is impossible to eliminate a warning. If a warning passes this "impossible to eliminate" test, the@SuppressWarnings annotation <b>must</b>
-be used, so as to ensure that all warnings reflect actual problems in the code.
-<p>When a @SuppressWarnings annotation is necessary, it must be prefixed with a TODO comment that explains the "impossible to eliminate" condition. This will normally identify an offending class that has an awkward interface. For example:
-</p>
-<pre>// TODO: The third-party class com.third.useful.Utility.rotate() needs generics <br>@SuppressWarnings({"generic-cast"})<br>ListStringblix = Utility.rotate(blax);<br></pre>
-When a @SuppressWarnings annotation is required, the code should be refactored to isolate the software elements where the annotation applies.
-<h2><a>Acronyms in names</a>
-</h2>
-<p>Treat acronyms and abbreviations as words. The names are much more readable:
-</p>
+<h4>Why?</h4>
+<p>Originally there was no style requirement on the ordering. This meant that
+the IDE's were either always changing the ordering, or IDE developers had to
+disable the automatic import management features and maintain the imports by
+hand. This was deemed bad. When java-style was asked, the preferred styles
+were all over the map. It pretty much came down to our needing to "pick an
+ordering and be consistent." So we chose a style, updated the style guide, and
+made the IDEs obey it. We expect that as IDE users work on the code, the
+imports in all of the packages will end up matching this pattern without any
+extra engineering effort.</p>
+<p>The style chosen such that:</p>
+<ul>
+<li>The imports people want to look at first tend to be at the top (android)</li>
+<li>The imports people want to look at least tend to be at the bottom (java)</li>
+<li>Humans can easily follow the style</li>
+<li>The IDE's can follow the style</li>
+</ul>
+<h3>What about static imports?</h3>
+<p>The use and location of static imports have been mildly controversial
+issues. Some people would prefer static imports to be interspersed with the
+remaining imports, some would prefer them reside above or below all other
+imports. Additinally, we have not yet come up with a way to make all IDEs use
+the same ordering.</p>
+<p>Since most people consider this a low priority issue, just use your
+judgement and please be consistent.</p>
-<table><tbody><tr><td>Good
-</td>
-<td>Bad
-</td>
-</tr>
-<tr><td>XmlHttpRequest</td>
-<td>XMLHTTPRequest
-</td>
-</tr>
-<tr><td>getCustomerId</td>
-<td>getCustomerID
-</td>
-</tr>
-</tbody>
-</table>
-
-<p>This style rule also applies when an acronym or abbreviation is the entire name:
-</p>
-
-<table><tbody><tr><td>Good
-</td>
-<td>Bad
-</td>
-</tr>
-<tr><td>class Html</td>
-<td>class HTML
-</td>
-</tr>
-<tr><td>String url;</td>
-<td>String URL;
-</td>
-</tr>
-<tr><td>long id;</td>
-<td>long ID;
-</td>
-</tr>
-</tbody>
-</table>
-
-<p>Both the JDK and the Android code bases are very inconsistent with regards to acronyms, therefore, it is virtually impossible to be consistent with the code around you. Bite the bullet, and treat acronyms as words.
-</p>
+<h2><a name="indentation"></a>Indentation</h2>
+<p>We use 4 space indents for blocks. We never use tabs. When in doubt, be
+consistent with code around you.</p>
+<p>We use 8 space indents for line wraps, including function calls and
+assignments. For example, this is correct:</p>
+<pre>Instrument i =
+ someLongExpression(that, wouldNotFit, on, one, line);</pre>
+<p>and this is not correct:</p>
+<pre>Instrument i =
+ someLongExpression(that, wouldNotFit, on, one, line);</pre>
+<h2><a name="field_names"></a>Field Names</h2>
+<ul>
+<li>Non-public, non-static field names start with m.</li>
+<li>Static field names start with s.</li>
+<li>Other fields start with a lower case letter.</li>
+<li>Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.</li>
+</ul>
+<p>For example:</p>
+<pre>public class MyClass {
+ public static final int SOME_CONSTANT = 42;
+ public int publicField;
+ private static MyClass sSingleton;
+ int mPackagePrivate;
+ private int mPrivate;
+ protected int mProtected;
+}</pre>
+<h2><a name="braces"></a>Braces</h2>
+<p>Braces do not go on their own line; they go on the same line as the code
+before them. So:</p>
+<pre>class MyClass {
+ int func() {
+ if (something) {
+ // ...
+ } else if (somethingElse) {
+ // ...
+ } else {
+ // ...
+ }
+ }
+}</pre>
+<p>We require braces around the statements for a conditional. Except, if the
+entire conditional (the condition and the body) fit on one line, you may (but
+are not obligated to) put it all on one line. That is, this is legal:</p>
+<pre>if (condition) {
+ body(); // ok
+}
+if (condition) body(); // ok</pre>
+<p>but this is still illegal:</p>
+<pre>if (condition)
+ body(); // bad</pre>
+<h2><a name="linelen"></a>Line length</h2>
+<p>Each line of text in your code should be at most 100 characters long.</p>
+<p>There has been lots of discussion about this rule and the decision remains
+that 100 characters is the maximum.</p>
+<p>Exception: if a comment line contains an example command or a literal URL
+longer than 100 characters, that line may be longer than 100 characters for
+ease of cut and paste.</p>
+<p>Exception: import lines can go over the limit because humans rarely see
+them. This also simplifies tool writing.</p>
+<h2><a name="annotations"></a>Java 1.5 Annotations</h2>
+<p>Annotations should precede other modifiers for the same language element.
+Simple marker annotations (e.g. @Override) can be listed on the same line with
+the language element. If there are multiple annotations, or parameterized
+annotations, they should each be listed one-per-line in alphabetical
+order.</p>
+<p>Android -standard practices for the three predefined annotations in Java
+1.5's are:</p>
+<h3>@Deprecated</h3>
+<p>The @Deprecated annotation must be used whenever the use of the annotated
+element is discouraged. If you use the @Deprecated annotation, you must also
+have a @deprecated Javadoc tag and it should name an alternate implementation.
+In addition, remember that a @Deprecated method is <b>still</b> supposed to
+work.</p>
+<p>If you see old code that has a @deprecated Javadoc tag, please add the @Deprecated annotation.</p>
+<h3>@Override</h3>
+<p>The @Override annotation must be used whenever a method overrides the
+declaration or implementation from a super-class.</p>
+<p>For example, if you use the @inheritdocs Javadoc tag, and derive from a
+class (not an interface), you must also annotate that the method @Overrides
+the parent class's method.</p>
+<h3>@SuppressWarnings</h3>
+<p>The @SuppressWarnings annotation should only be used under circumstances
+where it is impossible to eliminate a warning. If a warning passes this
+"impossible to eliminate" test, the @SuppressWarnings annotation <b>must</b> be
+used, so as to ensure that all warnings reflect actual problems in the
+code.</p>
+<p>When a @SuppressWarnings annotation is necessary, it must be prefixed with
+a TODO comment that explains the "impossible to eliminate" condition. This
+will normally identify an offending class that has an awkward interface. For
+example:</p>
+<pre>// TODO: The third-party class com.third.useful.Utility.rotate() needs generics
+@SuppressWarnings("generic-cast")
+List<String> blix = Utility.rotate(blax);</pre>
+<p>When a @SuppressWarnings annotation is required, the code should be
+refactored to isolate the software elements where the annotation applies.</p>
+<h2><a name="acronyms"></a>Acronyms in names</h2>
+<p>Treat acronyms and abbreviations as words. The names are much more readable:</p>
+<table><tbody>
+<tr><td>Good</td> <td>Bad</td></tr>
+<tr><td>XmlHttpRequest</td> <td>XMLHTTPRequest</td></tr>
+<tr><td>getCustomerId</td> <td>getCustomerID</td></tr>
+</tbody></table>
+<p>This style rule also applies when an acronym or abbreviation is the entire
+name:</p>
+<table><tbody>
+<tr><td>Good</td> <td>Bad</td></tr>
+<tr><td>class Html</td> <td>class HTML</td></tr>
+<tr><td>String url;</td> <td>String URL;</td></tr>
+<tr><td>long id;</td> <td>long ID;</td></tr>
+</tbody></table>
+<p>Both the JDK and the Android code bases are very inconsistent with regards
+to acronyms, therefore, it is virtually impossible to be consistent with the
+code around you. Bite the bullet, and treat acronyms as words.</p>
<p>For further justifications of this style rule, see <i>Effective Java</i>
-Item 38 and <i>Java Puzzlers</i>
-Number 68.
-</p>
-<h2><a>TODO style</a>
-</h2>
-<p>Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect.
-</p>
-<p>TODOs should include the string TODO in all caps, followed by a colon:
-</p>
-<pre>// TODO: Remove this code after the UrlTable2 has been checked in.<br><br>// TODO: Change this to use a flag instead of a constant.</pre>
-<p>If your TODO is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2005") or a very specific event ("Remove this code after all production mixers understand protocol V7.").
-</p>
-<h2>
-Consistency
-</h2>
-<p>Our parting thought: BE CONSISTENT. If you're editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around their if clauses, you should too. If their comments have little boxes of stars around them, make your comments have little boxes of stars around them too.
-</p>
-<p>The point of having style guidelines is to have a common vocabulary of coding, so people can concentrate on what you're saying, rather than on how you're saying it. We present global style rules here so people know the vocabulary. But local style is also important. If code you add to a a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Try to avoid this.
-</p>
-<h2><a>Logging</a>
-</h2>
-<p>While logging is necessary it has a significantly negative impact on performance and quickly loses its usefulness if it's not kept reasonably terse. The logging facilities provides five different levels of logging. Below are the different levels and when and how they should be used.
-</p>
+Item 38 and <i>Java Puzzlers</i> Number 68.</p>
-<ul><li><b>ERROR:</b>
-This level of logging should be used when something fatal has happened, i.e. something that will have user-visible consequences and won't be recoverable without explicitly deleting some data, uninstalling applications, wiping the data partitions or reflashing the entire phone (or worse). This level is always logged. Issues that justify some logging at the ERROR level are typically good candidates to be reported to a statistics-gathering server.
-</li>
+<h2><a name="todo"></a>TODO style</h2>
+<p>Use TODO comments for code that is temporary, a short-term solution, or
+good-enough but not perfect.</p>
+<p>TODOs should include the string TODO in all caps, followed by a colon:</p>
+<pre>// TODO: Remove this code after the UrlTable2 has been checked in.
+
+// TODO: Change this to use a flag instead of a constant.</pre>
+<p>If your TODO is of the form "At a future date do something" make sure that
+you either include a very specific date ("Fix by November 2005") or a very
+specific event ("Remove this code after all production mixers understand
+protocol V7.").</p>
+
+<h2><a name="consistency"></a>Consistency</h2>
+<p>Our parting thought: BE CONSISTENT. If you're editing code, take a few
+minutes to look at the code around you and determine its style. If they use
+spaces around their if clauses, you should too. If their comments have little
+boxes of stars around them, make your comments have little boxes of stars
+around them too.</p>
+<p>The point of having style guidelines is to have a common vocabulary of
+coding, so people can concentrate on what you're saying, rather than on how
+you're saying it. We present global style rules here so people know the
+vocabulary. But local style is also important. If code you add to a a file
+looks drastically different from the existing code around it, it throws
+readers out of their rhythm when they go to read it. Try to avoid this.</p>
+
+<h2><a name="logging"></a>Logging</h2>
+<p>While logging is necessary it has a significantly negative impact on
+performance and quickly loses its usefulness if it's not kept reasonably
+terse. The logging facilities provides five different levels of logging. Below
+are the different levels and when and how they should be used.</p>
+
+<ul>
+<li><b>ERROR:</b>
+This level of logging should be used when something fatal has happened,
+i.e. something that will have user-visible consequences and won't be
+recoverable without explicitly deleting some data, uninstalling applications,
+wiping the data partitions or reflashing the entire phone (or worse). This
+level is always logged. Issues that justify some logging at the ERROR level
+are typically good candidates to be reported to a statistics-gathering
+server.</li>
<li><b>WARNING:</b>
-This level of logging should used when something serious and unexpected happened, i.e. something that will have user-visible consequences but is likely to be recoverable without data loss by performing some explicit action, ranging from waiting or restarting an app all the way to re-downloading a new version of an application or rebooting the device. This level is always logged. Issues that justify some logging at the WARNING level might also be considered for reporting to a statistics-gathering server.
-</li>
+This level of logging should used when something serious and unexpected
+happened, i.e. something that will have user-visible consequences but is
+likely to be recoverable without data loss by performing some explicit action,
+ranging from waiting or restarting an app all the way to re-downloading a new
+version of an application or rebooting the device. This level is always
+logged. Issues that justify some logging at the WARNING level might also be
+considered for reporting to a statistics-gathering server.</li>
<li><b>INFORMATIVE:</b>
-This level of logging should used be to note that something interesting to most people happened, i.e. when a situation is detected that is likely to have widespread impact, though isn't necessarily an error. Such a condition should only be logged by a module that reasonably believes that it is the most authoritative in that domain (to avoid duplicate logging by non-authoritative components). This level is always logged.
-</li>
+This level of logging should used be to note that something interesting to
+most people happened, i.e. when a situation is detected that is likely to have
+widespread impact, though isn't necessarily an error. Such a condition should
+only be logged by a module that reasonably believes that it is the most
+authoritative in that domain (to avoid duplicate logging by non-authoritative
+components). This level is always logged.</li>
<li><b>DEBUG:</b>
-This level of logging should be used to further note what is happening on the device that could be relevant to investigate and debug unexpected behaviors. You should log only what is needed to gather enough information about what is going on about your component. If your debug logs are dominating the log then you probably should be using verbose logging. This level will be logged, even on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if (LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or subcomponent, so that there can exist a possibility to disable all such logging. There must therefore be no active logic in an if (LOCAL_LOG) block. All the string building for the log also needs to be placed inside the if (LOCAL_LOG) block. The logging call should not be re-factored out into a method call if it is going to cause the string building to take place outside of the if (LOCAL_LOG) block. There is some code that still says if (localLOGV). This is considered acceptable as well, although the name is nonstandard.
-</li>
+This level of logging should be used to further note what is happening on the
+device that could be relevant to investigate and debug unexpected behaviors.
+You should log only what is needed to gather enough information about what is
+going on about your component. If your debug logs are dominating the log then
+you probably should be using verbose logging. This level will be logged, even
+on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if
+(LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or
+subcomponent, so that there can exist a possibility to disable all such
+logging. There must therefore be no active logic in an if (LOCAL_LOG) block.
+All the string building for the log also needs to be placed inside the if
+(LOCAL_LOG) block. The logging call should not be re-factored out into a
+method call if it is going to cause the string building to take place outside
+of the if (LOCAL_LOG) block. There is some code that still says if
+(localLOGV). This is considered acceptable as well, although the name is
+nonstandard.</li>
<li><b>VERBOSE:</b>
-This level of logging should be used for everything else. This level will only be logged on debug builds and should be surrounded by if (LOCAL_LOGV) block (or equivalent) so that it can be compiled out by default. Any string building will be stripped out of release builds and needs to appear inside the if (LOCAL_LOGV) block.
-</li>
+This level of logging should be used for everything else. This level will only
+be logged on debug builds and should be surrounded by if (LOCAL_LOGV) block
+(or equivalent) so that it can be compiled out by default. Any string building
+will be stripped out of release builds and needs to appear inside the if
+(LOCAL_LOGV) block.</li>
</ul>
-<p><i>Note:</i>
-Within a given module, other than at the VERBOSE level, an error should only be reported once if possible: within a single chain of function calls within a module, only the innermost function should return the error, and callers in the same module should only add some logging if that significantly helps to isolate the issue.
-</p>
-<p><i>Note:</i>
-In a chain of modules, other than at the VERBOSE level, when a lower-level module detects invalid data coming from a higher-level module, the lower-level module should only log this situation to the DEBUG log, and only if logging provides information that is not otherwise available to the caller. Specifically, there is no need to log situations where an exception is thrown (the exception should contain all the relevant information), or where the only information being logged is contained in an error code. This is especially important in the interaction between the framework and applications, and conditions caused by third-party applications that are properly handled by the framework should not trigger logging higher than the DEBUG level. The only situations that should trigger logging at the INFORMATIVE level or higher is when a module or application detects an error at its own level or coming from a lower level.
-</p>
-<p><i>Note:</i>
-When a condition that would normally justify some logging is likely to occur many times, it can be a good idea to implement some rate-limiting mechanism to prevent overflowing the logs with many duplicate copies of the same (or very similar) information.
-</p>
-<p><i>Note:</i>
-Losses of network connectivity are considered common and fully expected and should not be logged gratuitously. A loss of network connectivity that has consequences within an app should be logged at the DEBUG or VERBOSE level (depending on whether the consequences are serious enough and unexpected enough to be logged in a release build).
-</p>
-<p><i>Note:</i>
-A full filesystem on a filesystem that is acceessible to or on behalf of third-party applications should not be logged at a level higher than INFORMATIVE.
-</p>
-<p><i>Note:</i>
-Invalid data coming from any untrusted source (including any file on shared storage, or data coming through just about any network connections) is considered expected and should not trigger any logging at a level higher then DEBUG when it's detected to be invalid (and even then logging should be as limited as possible).
-</p>
-<p><i>Note:</i>
-Keep in mind that the '+' operator, when used on Strings, implicitly creates a StringBuilder with the default buffer size (16 characters) and potentially quite a few other temporary String objects, i.e. that explicitly creating StringBuilders isn't more expensive than relying on the default '+' operator (and can be a lot more efficient in fact). Also keep in mind that code that calls Log.v() is compiled and executed on release builds, including building the strings, even if the logs aren't being read.
-</p>
-<p><i>Note:</i>
-Any logging that is meant to be read by other people and to be available in release builds should be terse without being cryptic, and should be reasonably understandable. This includes all logging up to the DEBUG level.
-</p>
-<p><i>Note:</i>
-When possible, logging should be kept on a single line if it makes sense. Line lengths up to 80 or 100 characters are perfectly acceptable, while lengths longer than about 130 or 160 characters (including the length of the tag) should be avoided if possible.
-</p>
-<p><i>Note:</i>
-Logging that reports successes should never be used at levels higher than VERBOSE.
-</p>
-<p><i>Note:</i>
-Temporary logging that is used to diagnose an issue that's hard to reproduce should be kept at the DEBUG or VERBOSE level, and should be enclosed by if blocks that allow to disable it entirely at compile-time.
-</p>
-<p><i>Note:</i>
-Be careful about security leaks through the log. Private information should be avoided. Information about protected content must definitely be avoided. This is especially important when writing framework code as it's not easy to know in advance what will and will not be private information or protected content.
-</p>
-<p><i>Note:</i>
-System.out.println() (or printf() for native code) should never be used. System.out and System.err get redirected to /dev/null, so your print statements will have no visible effects. However, all the string building that happens for these calls still gets executed.
-</p>
-<p><i>Note:</i>
-<b>The golden rule of logging is that your logs may not unnecessarily push other logs out of the buffer, just as others may not push out yours.</b>
-</p>
-<h2>
-Javatests Style Rules
-</h2>
+<p><i>Note:</i> Within a given module, other than at the VERBOSE level, an
+error should only be reported once if possible: within a single chain of
+function calls within a module, only the innermost function should return the
+error, and callers in the same module should only add some logging if that
+significantly helps to isolate the issue.</p>
+<p><i>Note:</i> In a chain of modules, other than at the VERBOSE level, when a
+lower-level module detects invalid data coming from a higher-level module, the
+lower-level module should only log this situation to the DEBUG log, and only
+if logging provides information that is not otherwise available to the caller.
+Specifically, there is no need to log situations where an exception is thrown
+(the exception should contain all the relevant information), or where the only
+information being logged is contained in an error code. This is especially
+important in the interaction between the framework and applications, and
+conditions caused by third-party applications that are properly handled by the
+framework should not trigger logging higher than the DEBUG level. The only
+situations that should trigger logging at the INFORMATIVE level or higher is
+when a module or application detects an error at its own level or coming from
+a lower level.</p>
+<p><i>Note:</i> When a condition that would normally justify some logging is
+likely to occur many times, it can be a good idea to implement some
+rate-limiting mechanism to prevent overflowing the logs with many duplicate
+copies of the same (or very similar) information.</p>
+<p><i>Note:</i> Losses of network connectivity are considered common and fully
+expected and should not be logged gratuitously. A loss of network connectivity
+that has consequences within an app should be logged at the DEBUG or VERBOSE
+level (depending on whether the consequences are serious enough and unexpected
+enough to be logged in a release build).</p>
+<p><i>Note:</i> A full filesystem on a filesystem that is acceessible to or on
+behalf of third-party applications should not be logged at a level higher than
+INFORMATIVE.</p>
+<p><i>Note:</i> Invalid data coming from any untrusted source (including any
+file on shared storage, or data coming through just about any network
+connections) is considered expected and should not trigger any logging at a
+level higher then DEBUG when it's detected to be invalid (and even then
+logging should be as limited as possible).</p>
+<p><i>Note:</i> Keep in mind that the '+' operator, when used on Strings,
+implicitly creates a StringBuilder with the default buffer size (16
+characters) and potentially quite a few other temporary String objects, i.e.
+that explicitly creating StringBuilders isn't more expensive than relying on
+the default '+' operator (and can be a lot more efficient in fact). Also keep
+in mind that code that calls Log.v() is compiled and executed on release
+builds, including building the strings, even if the logs aren't being
+read.</p>
+<p><i>Note:</i> Any logging that is meant to be read by other people and to be
+available in release builds should be terse without being cryptic, and should
+be reasonably understandable. This includes all logging up to the DEBUG
+level.</p>
+<p><i>Note:</i> When possible, logging should be kept on a single line if it
+makes sense. Line lengths up to 80 or 100 characters are perfectly acceptable,
+while lengths longer than about 130 or 160 characters (including the length of
+the tag) should be avoided if possible.</p>
+<p><i>Note:</i> Logging that reports successes should never be used at levels
+higher than VERBOSE.</p>
+<p><i>Note:</i> Temporary logging that is used to diagnose an issue that's
+hard to reproduce should be kept at the DEBUG or VERBOSE level, and should be
+enclosed by if blocks that allow to disable it entirely at compile-time.</p>
+<p><i>Note:</i> Be careful about security leaks through the log. Private
+information should be avoided. Information about protected content must
+definitely be avoided. This is especially important when writing framework
+code as it's not easy to know in advance what will and will not be private
+information or protected content.</p>
+<p><i>Note:</i> System.out.println() (or printf() for native code) should
+never be used. System.out and System.err get redirected to /dev/null, so your
+print statements will have no visible effects. However, all the string
+building that happens for these calls still gets executed.</p>
+<p><i>Note:</i> <b>The golden rule of logging is that your logs may not
+unnecessarily push other logs out of the buffer, just as others may not push
+out yours.</b></p>
-<h2><a>Naming test methods</a>
-</h2>
-<a>When naming test methods, you can use an underscore to seperate what is being tested from the specific case being tested. This style makes it easier to see exactly what cases are being tested.</a>
-<p><a>Example:</a>
-</p>
-<pre><a>testMethod_specificCase1 <br>testMethod_specificCase2</a>
-</pre>
+<h2>Javatests Style Rules</h2>
+<h2><a name="testmethodnames"></a>Naming test methods</h2>
+<p>When naming test methods, you can use an underscore to seperate what is
+being tested from the specific case being tested. This style makes it easier
+to see exactly what cases are being tested.</p>
+<p><a>For example:</a></p>
+<pre>testMethod_specificCase1 testMethod_specificCase2</pre>
-<pre><a>void testIsDistinguishable_protanopia() {<br>ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)<br>assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))<br>assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))<br>}</a>
+<pre>void testIsDistinguishable_protanopia() {
+ ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)
+ assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))
+ assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))
+}
</pre>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/download.jd b/pdk/docs/source/download.jd
index 329deff..65bcc70 100644
--- a/pdk/docs/source/download.jd
+++ b/pdk/docs/source/download.jd
@@ -1,303 +1,202 @@
page.title=Get Android Source Code
doc.type=source
@jd:body
-<div><br>This document describes how to set up your local work environment, how to use Repo to get the Android files, and how to build the files on your machine.<br><br>Related reading:<br></div>
-<ul><li>For an overview of the entire code-review and code-update process, see
-<a href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>
-.</li>
-<li>For reference details about Repo, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>
-.<br></li>
-</ul>
-<h2>
-What's in the source?</h2>
-<div>To see snapshots and histories of the files available in the public Android repositories, visit the <a href="http://android.git.kernel.org/">GitWeb</a>
-web interface.</div>
-<div></div>
-<div>The source is approximately 2.1GB in size. You will need 6GB free to complete the build.<br><br></div>
-<h2>
-Setting up your machine</h2>
-<div>To build the Android source files, you will need to use Linux or Mac OS. Building under Windows is not currently supported.</div>
-<div><br></div>
-<h3>
-Linux</h3>
-The Android build is routinely tested on recent versions of Ubuntu (6.06 and later), but reports of successes or failures on other distributions are welcome.<br><h4>
-Ubuntu Linux (32-bit x86)</h4>
-<div>To set up your Linux development environment, make sure you have the following:</div>
-<div><div><div><ul><li>Required Packages:</li>
-<ul><li>Git 1.5.4 or newer <span>and the GNU Privacy Guard.<br></span>
-</li>
-</ul>
-</ul>
+
+<div>
+ <p>This document describes how to set up your local work environment, how to use Repo to get the Android files, and how to build the files on your machine.</p>
+ <p>Related reading:
+ <ul>
+ <li>For an overview of the entire code-review and code-update process, see
+<a href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>.</li>
+ <li>For reference details about Repo, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>.</li>
+ </ul>
+ </p>
</div>
+
+<div>
+ <h2>What's in the source?</h2>
+ <p>To see snapshots and histories of the files available in the public Android repositories, visit the <a href="http://android.git.kernel.org/">GitWeb</a> web interface.</p>
+ <p>The source is approximately 2.6GB in size. You will need 6GB free to complete the build.</p>
</div>
+
+<div>
+ <h2>Setting up your machine</h2>
+ <p>To build the Android source files, you will need to use Linux or Mac OS. Building under Windows is not currently supported.</p>
+
+ <h3>Linux</h3>
+ <p>The Android build is routinely tested in house on recent versions of Ubuntu (10.04 and later), but most distributions should have the required build tools available. Reports of successes or failures on other distributions are welcome.</p>
+ <p>In general you will need:
+ <ul>
+ <li>Python 2.4, which you can download from <a href="http://www.python.org/download/">python.org</a>.</li>
+ <li>JDK 6 if you wish to build Gingerbread or newer; JDK 5 for Froyo or older. You can download either from <a href="http://java.sun.com/javase/downloads/">java.sun.com</a>.</li>
+ <li>Git 1.5.4 or newer. You can find it at <a href="http://git.or.cz/">http://git.or.cz/</a>.</li>
+ </ul>
+ </p>
+
+ <h4>Ubuntu Linux (64-bit)</h4>
+ <p>The Sun JDK is no longer in Ubuntu's main package repository. In order to download it, you need to add the appropriate repository and indicate to the system which JDK should be used.
+ <p>Java 6: for Gingerbread and newer
+ <div class=code>sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"<br/>
+ sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner"<br/>
+ sudo apt-get update<br/>
+ sudo apt-get install sun-java6-jdk<br/>
+ sudo update-java-alternatives -s java-6-sun
+ </div>
+ </p>
+ <p>Java 5: for Froyo and older
+ <div class=code>sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper main multiverse"<br/>
+ sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper-updates main multiverse"<br/>
+ sudo apt-get update<br/>
+ sudo apt-get install sun-java5-jdk<br/>
+ sudo update-java-alternatives -s java-1.5.0-sun
+ </div>
+ </p>
+ </p>
+ <p>To set up your development environment, install the following required packages:
+ <div class=code>$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev</div>
+ </p>
+ <p>You might also want Valgrind, a tool that will help you find memory leaks, stack corruption, array bounds overflows, etc.</p>
+
+ <h4>Running Linux in a virtual machine</h4>
+If you are running Linux in a virtual machine, you will need at least 1.5GB of RAM and 10GB or more of disk space in order to build the Android tree.<br>
+</div>
+
+<div>
+ <h3>Mac OS X</h3>
+ <p>To build the Android files in a Mac OS environment, you need an Intel/x86 machine running MacOS 10.4 (Tiger), 10.5 (Leopard), or 10.6 (Snow Leopard). The Android build system and tools do not support the obsolete PowerPC architecture.</p>
+ <p>Android must be built on a case-sensitive file system because the sources contain files that differ only in case. We recommend that you build Android on a partition that has been formatted with the journaled file system HFS+. HFS+ is required to successfully build Mac OS applications such as the Android Emulator for OS X.</p>
+ <div>
+ <h4>Creating a case sensitive disk image</h4>
+ <p>If you want to avoid partitioning/formatting your hard drive, you can use a case-sensitive disk image instead. To create the image, launch Disk Utility and select "New Image". A size of 8 GB is sufficient, or more if you prefer. Be sure to select "case sensitive, journaled" as the volume format.</p>
+ <p>This will create a .dmg file which, once mounted, acts as a drive with the required formatting for Android development. For a disk image named "android.dmg" stored in your home directory, you can add the following to your <tt>~/.bash_profile</tt> to mount the image when you execute "mountAndroid":
+ <div class=code># mount the android file image<br/>
+ function mountAndroid{ hdiutil attach ~/android.dmg-mountpoint /Volumes/android; }</div>
+ Once mounted, you'll do all your work in the "android" volume. You can eject it (unmount it) just like you would with an external drive.</p>
+ </div>
+
+ <p>To set up your Mac OS development environment, follow these steps:
+ <ol>
+ <li>Install XCode from <a href="http://developer.apple.com/">http://developer.apple.com</a>. We recommend version 3.0 or newer. If you are not already registered as an Apple developer, you will have to create an Apple ID in order to download.</li>
+ <li>Install MacPorts from <a href="http://www.macports.org/install.php">http://www.macports.org/</a>.</li>
+ <li>Make sure that /opt/local/bin appears in your path BEFORE /usr/bin. If not, add
+ <div class=code>export PATH=/opt/local/bin:$PATH</div>
+ to your <tt>~/.bash_profile</tt>.</li>
+ <li>Get make, git, and GPG packages from port:
+ <div class=code>$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg</div>
+ If using Mac OS 10.4, also install bison:
+ <div class=code>$ POSIXLY_CORRECT=1 sudo port install bison</div>
+ </li>
+ <li>Temporary step: There is a bug in gmake 3.82 that prevents android from building. You can install version 3.81 using MacPorts by taking the following steps:
+ <p>Edit <tt>/opt/local/etc/macports/sources.conf</tt> and a line that says <div class=code>file:///Users/Shared/dports</div> above the rsync line. Then create this directory: <div class=code>$ mkdir /Users/Shared/dports</div>
+ In the new <tt>dports</tt> directory, run <div class=code>$ svn co --revision 50980 http://svn.macports.org/repository/macports/trunk/dports/devel/gmake/ devel/gmake/</div>
+ Create a port index for your new local repository: <div class=code>$ portindex /Users/Shared/dports</div>
+ Finally, install the old version of gmake with <div class=code>$ sudo port install gmake @3.81</div>
+ </p>
+ </li>
+ <li>Set an appropriate per-process file descriptor limit. To do this, add the following lines to your <tt>~/.bash_profile</tt>: <div class=code># set the number of open files to be 1024<br/>
+ ulimit -S -n 1024</div>
+ </li>
+ </ol>
+ </p>
</div>
+
+
+<div>
+ <h2>Installing Repo</h2>
+ <p>Repo is a tool that makes it easier to work with Git in the context of Android. For more information about Repo, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>.</p>
+ <p>To install, initialize, and configure Repo, follow these steps:
+ <ol>
+ <li>Make sure you have a bin/ directory in your home directory, and that it is included in your path:
+ <div class=code>$ mkdir ~/bin<br/>
+ $ PATH=~/bin:$PATH</div>
+ </li>
+ <li>Download the Repo script and ensure it is executable:
+ <div class=code>$ curl http://android.git.kernel.org/repo > ~/bin/repo<br/>
+ $ chmod a+x ~/bin/repo</div>
+ </li>
+ </ol>
</div>
-<div><div><div><div><ul><ul><li>JDK 5.0, update 12 or higher.Java 6 is not supported, because of incompatibilities with @Override.<br></li>
-</ul>
-</ul>
+
+<div>
+ <h2>Initializing a Repo client</h2>
+ <p>After installing Repo, set up your client to access the android source repository:
+ <ol>
+ <li>Create an empty directory to hold your working files:
+ <div class=code>$ mkdir <i>directory</i><br/>
+ $ cd <i>directory</i></div>
+ </li>
+ <li>Run <tt>repo init</tt> to bring down the latest version of Repo with all its most recent bug fixes. You must specify a URL for the manifest, which specifies where the various repositories included in the Android source will be placed within your working directory.
+ <div class=code>$ repo init -u git://android.git.kernel.org/platform/manifest.git</div>
+ To check out a branch other than "master", specify it with -b:
+ <div class=code>$ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake</div>
+ </li>
+ <li>When prompted, please configure Repo with your real name and email address. To use the Gerrit code-review tool, you will need an email address that is connected with a <a href="http://www.google.com/accounts">registered Google account</a>. Make sure this is a live address at which you can receive messages. The name that you provide here will show up in attributions for your code submissions.
+ </li>
+ </ol>
+ A successful initialization will end with a message stating that Repo is initialized in your working directory. Your client directory should now contain a <tt>.repo</tt> directory where files such as the manifest will be kept.</p>
</div>
+
+<div>
+ <h2>Getting the files</h2>
+ <p>To pull down files to your working directory from the repositories as specified in the default manifest, run
+ <div class=code>$ repo sync</div>
+ For more about <tt>repo sync</tt> and other Repo commands, see <a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>.</span>
+ <p>The Android source files will be located in your working directory under their project names.</p>
</div>
+
+<div>
+ <h2>Verifying Git Tags</h2>
+ <p>Load the following public key into your GnuPG key database. The key is used to sign annotated tags that represent releases.
+ <div class=code>$ gpg --import</div>
+ Copy and paste the key(s) below, then enter EOF (Ctrl-D) to end the input and process the keys.
+ <div class=code>-----BEGIN PGP PUBLIC KEY BLOCK-----<br>
+ Version: GnuPG v1.4.2.2 (GNU/Linux)<br><br>
+ mQGiBEnnWD4RBACt9/h4v9xnnGDou13y3dvOx6/t43LPPIxeJ8eX9WB+8LLuROSV <br>
+ lFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw7<br>
+ 8tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMD <br>
+ u4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0Z <br>
+ wNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq <br>
+ /HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5<br>
+ jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4<br>
+ MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9<br>
+ b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJv <br>
+ aWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5k <br>
+ cm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX <br>
+ gAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI <br>
+ 2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAl <br>
+ QN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806Up <br>
+ hisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbk <br>
+ C2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMX <br>
+ LWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+<br>
+ OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/M <br>
+ pK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7s <br>
+ KZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phb <br>
+ N8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjA <br>
+ vUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwo <br>
+ G1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQ <br>
+ hN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0l <br>
+ EXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+jv2QSTlrx4KLM=<br>
+ =Wi5D <br>
+ -----END PGP PUBLIC KEY BLOCK-----
+ </div>
+ After importing the keys, you can verify any tag with <div class=code>$ git tag -v <i>tagname</i></div>
+ </p>
</div>
+
+<div>
+ <h2>Building the code</h2>
+ <p>To build the files, run envsetup, lunch, and make from within your working directory:
+ <div class=code>$ cd ~/<i>directory</i><br/>
+ $ source build/envsetup.sh<br/>
+ $ lunch<br/>
+ $ make<br/>
+ </div>
+ If your build fails because of a missing <tt>run-java-tool</tt>, try setting the <tt>ANDROID_JAVA_HOME</tt> environment variable before making.
+ <div class=code>$ export ANDROID_JAVA_HOME=$JAVA_HOME</div>
+ </p>
</div>
-<div><div><div><div><ul><ul><li><span>flex, bison, gperf, libsdl-dev, libesd0-dev, libwxgtk2.6-dev (optional), build-essential, zip, curl.</span>
-</li>
-</ul>
-</ul>
-</div>
-</div>
-</div>
-</div>
-<blockquote><span>$ sudo apt-get install</span>
-<span>git-core gnupg</span>
-<span>sun-java5-jdk</span>
-<span>flex bison gperf <span>libsdl-dev libesd0-dev</span>
-libwxgtk2.6-dev build-essential zip <span>curl libncurses5-dev zlib1g-dev <br></span>
-</span>
-</blockquote>
-<div><div><div><div><ul><li><span><span>You might also want Valgrind, a tool that will help you find memory leaks, stack corruption, array bounds overflows, etc.</span>
-</span>
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
-<blockquote><div><span>$ sudo apt-get install valgrind <br></span>
-</div>
-</blockquote>
-<ul><li><span><span>Intrepid (</span>
-</span>
-8.10) users may need a newer version of libreadline:</li>
-</ul>
-<div>$ sudo apt-get install lib32readline5-dev <br></div>
-</div>
-<div><div><div><div><div><div><h4>
-Ubuntu Linux (64-bit x86)</h4>
-This has not been as well tested. Please send success or failure reports to <a href="mailto:android-porting@googlegroups.com">android-porting@googlegroups.com</a>
-.</div>
-<div><br></div>
-<div>The Android build requires a 32-bit build environment as well as some other tools:<br></div>
-<div><ul><li>Required Packages:</li>
-<ul><li>Git, JDK, flex, and the other packages as listed above in the i386 instructions:<span><br></span>
-</li>
-<li>JDK 5.0, update 12 or higher.Java 6 is not supported, because of incompatibilities with @Override.</li>
-<li>Pieces from the 32-bit cross-building environment</li>
-<li>X11 development <br></li>
-</ul>
-</ul>
-</div>
-</div>
-</div>
-</div>
-<blockquote><span><span>$</span>
-sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl</span>
-sun-java5-jdk <span><span>zlib1g-dev</span>
-</span>
-gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev</blockquote>
-<ul><li>Set the system to use the right version of java by default:<br><br>$sudo update-java-alternatives -sjava-1.5.0-sun <br></li>
-</ul>
-<ul><li>X11: Ubuntu doesn't have packages for the X11 libraries, but that can be worked around with the following command:<br><br>$ sudo ln -s /usr/lib32/libX11.so.6 /usr/lib32/libX11.so <br><br></li>
-</ul>
-<div><div><div><div><div><h4>
-Running Linux in a virtual machine</h4>
-If you are running Linux in a virtual machine, you will need at least 1.5GB of RAM and 10GB or more of disk space in order to build the Android tree.<br><h4>
-Other Linux</h4>
-<p>There's no reason why Android cannot be built on non-Ubuntu systems. Please send any success or failure reports to <a href="mailto:android-porting@googlegroups.com">android-porting@googlegroups.com</a>
-<span>. In general you will need:</span>
-</p>
-<ul><li>Python 2.4, which you can <a href="http://www.python.org/download/">download from python.org</a>.</li>
-<li>JDK 5.0, update 12 or higher, which you can <a href="http://java.sun.com/javase/downloads/">download from java.sun.com</a>. Java 6 is not supported, because of incompatibilities with @Override.</li>
-<li>Git 1.5.4 or newer. You can find it at <a href="http://git.or.cz/">http://git.or.cz/</a>.</li>
-</ul>
-<p>Anything missing from this list? Please let us know!</p>
-<h4>
-<span><br></span>
-</h4>
-</div>
-<div><h3>
-Mac OS <br></h3>
-</div>
-<div><p><span>Requirements:</span>
-</p>
-<ul><li><span>To build the Android files in a Mac OS environment, you need an Intel/x86 machine running MacOS 10.4 ("Tiger") or 10.5 ("Leopard"). At the moment MacOS 10.6 ("Snow Leopard") is not supported. The Android build system and tools do not support the obsolete PowerPC architecture.</span>
-</li>
-<li><span>Android must be built on a case-sensitive file system.<br></span>
-</li>
-<ul><li>We recommend that you build Android on a partition that has been formatted with the "Case-sensitive Journaled HFS+" file system:</li>
-<ul><li>A case-sensitive file system is required because the sources contain files that differ only in case.</li>
-<li>Journaled systems are more robust. (This is optional, but recommended.)</li>
-<li>HFS+ is required to successfully build Mac OS applications such as the Android Emulator for OS X.</li>
-</ul>
-<li>If you want to avoid partitioning/formatting your hard drive, you can use a case-sensitive disk image instead.</li>
-<ul><li>To create the image:<br><ul><li>launch /Applications/Utilities/Disk Utility</li>
-<li>select "New Image"</li>
-<li>size: 8 GB (this will work, but you can choose more if you want to)</li>
-<li>volume format: case sensitive, journaled</li>
-</ul>
-</li>
-<li>This will create a .dmg file which, once mounted, acts as a drive with the required formatting for Android development. For a disk image named "android.dmg" stored in your home directory, you can add the following to your ~/.bash_profile to mount the image when you execute "mountAndroid":<br><br><div># command to mount the android file image <br>function mountAndroid{ hdiutil attach ~/android.dmg-mountpoint /Volumes/android; }<br></div>
-<br>Once mounted, you'll do all your work in the "android" volume. You can eject it (unmount it) just like you would with an external drive.</li>
-</ul>
-</ul>
-</ul>
-<ul></ul>
-To set up your Mac OS development environment, follow these steps:<br><ol><li>Install the XCode version 2.4 or later from <a href="http://developer.apple.com/">http://developer.apple.com</a>. We recommend version 3.0 or newer.<br></li>
-<li>Install MacPorts. To do this:</li>
-<ol><li>Download the tar file from <a href="http://www.macports.org/">http://www.macports.org/</a> and untar the files.</li>
-<li>Run the following:<span><br>$ ./configure <br></span>
-<span>$</span>
-<span>make <br></span>
-<span>$</span>
-<span>sudo make install</span>
-</li>
-<li>Make sure that /opt/local/bin is in your path before /usr/bin. by running <br>$ echo $PATH <br>If you don't see /opt/local/bin, edit $HOME/.bash_profile and add the line <br>export PATH=/opt/local/bin:$PATH <br>(or the equivalent for other shells) after any other PATH-related lines.<span>To verify that your path is now correct, o</span>
-pen a new terminal and <span>run</span>
-echo $PATH <span>again</span>
-.</li>
-<li>Ask MacPorts to update itself:<br><span></span>
-<span>$</span>
-<span>sudo port selfupdate</span>
-<br></li>
-</ol>
-<li>Get the following packages from port:<br>$<span>POSIXLY_CORRECT=1</span>
-sudo port install gmake libsdl git-core gnupg <br><span>If using Mac OS 10.4, also install:<br>$<span>POSIXLY_CORRECT=1</span>
-sudo port install bison <br></span>
-</li>
-<li>Upgrade GNU make to 3.81 or later by running.Mac OS doesn't come with a recent enough version.<br>$ sudo ln -s gmake /opt/local/bin/make <br></li>
-<li>Set an appropriate per-process file descriptor limit. To do this, add the following lines to your <i><span>.bash_profile</span>
-</i>
-file:<br># set the number of open files to be 1024<br>ulimit -S -n 1024</li>
-</ol>
-</div>
-</div>
-</div>
-<div><br></div>
-<h2>
-Installing Repo <br></h2>
-<div><p>Repo is a tool that makes it easier to work with Git in the context of
-Android. For more information about Repo, see <a
-href="{@docRoot}source/git-repo.html">Using Repo and Git</a>
-.<br></p>
-To install, initialize, and configure Repo, follow these steps:<br><br></div>
-<ol><li><span>Make sure you have a~/bindirectory in your home directory, and check to be sure that this bin directory is in your path:</span>
-<br>$ cd~<br><span><span>$ mkdir bin <br>$ echo $PATH <br></span>
-</span>
-</li>
-<li><span>Download thereposcript and make sure it is executable:</span>
-<br>$ curl http://android.git.kernel.org/repo~/bin/repo <div>$ chmod a+x ~/bin/repo</div>
-</li>
-</ol>
-</div>
-<div><p><br></p>
-<h2>
-Initializing a Repo client <br></h2>
-</div>
-<div><ol><li><span>Create an empty directory to hold your working files:</span>
-<span><br></span>
-<span>$ mkdir mydroid</span>
-<br><span>$ cd mydroid</span>
-<br></li>
-<li><span>Runrepo initto bring down the latest version of Repo with all its most recent bug fixes. You must specify a URL for the manifest:</span>
-<br><span>$ repo init</span>
--u git://android.git.kernel.org/platform/manifest.git</li>
-<ul><li><span>If you would like to check out a branch other than "master", specify it with -b, like:</span>
-<br><span>$ repo init</span>
--u git://android.git.kernel.org/platform/manifest.git -b cupcake <br></li>
-</ul>
-<li><span>When prompted, configure Repo with your real name and email address. If you plan to submit code, use an email address that is associated with a <a href="https://www.google.com/accounts">Google account</a>
-.</span>
-<br></li>
-</ol>
-<span><span>A successful initialization will end with a message such as</span>
-<br><span>repo</span>
-initialized in /mydroid</span>
-<br><span><span><br>Your client directory should now contain a.repodirectory where files such as the manifest will be kept.</span>
-<br><br></span>
-<span><span><b>What will my name and email be used for?</b>
-<br></span>
-<span><br>To use the Gerrit code-review tool,</span>
-<span>you will need an email address that is connected with a <a href="http://www.google.com/accounts">registered Google account</a>
-(which does not have to be a Gmail address). Make sure this is</span>
-<span>a live address</span>
-<span>at which you can receive messages</span>
-<span>.</span>
-<span>The real name that you provide here will show up in attributions for your code submissions.</span>
-</span>
-<br></div>
-<span><p><b>What is a manifest file?</b>
-</p>
-<p><span>The Android source files are divided among a number of different repositories.</span>
-<span>A manifest</span>
-<span>file contains a mapping of where the files from these repositories will be placed within your working directory w</span>
-<span>hen you synchronize your files.<br></span>
-</p>
-<p><span><br></span>
-</p>
-</span>
-<h2>
-Getting the files</h2>
-<div><span><span>To pull down files to your working directory from the repositories as specified in the default manifest, run</span>
-<br><br>$ repo sync <i><br></i>
-<br><span>For more aboutrepo syncand other Repo commands, see</span>
-<a href="{@docRoot}source/git-repo.html">Using Repo and Git</a>
-<span>.</span>
-<br><br><span>The Android source files will be located in your working
-directory under their project names.</span>
-</span>
-<br></div>
-<span><h2>
-<br></h2>
-<h2>
-Verifying Git Tags</h2>
-<span>Load the following public key into your GnuPG key database.The key is used to sign annotated tags that represent releases.</span>
-<br><br></span>
-<span>$ gpg --import <br><br></span>
-<span><span>then paste the key(s) below, and press Control-D to end the input and process the keys.</span>
-After importing the keys, you can verify any tag with <br><br></span>
-<span>$ git tag -v <i>tagname</i>
-</span>
-<span><br><br><b><u>key 9AB10E78: "The Android Open Source Projectinitial-contribution@android.com"</u>
-</b>
-<br></span>
-<pre>-----BEGIN PGP PUBLIC KEY BLOCK-----<br>Version: GnuPG v1.4.2.2 (GNU/Linux)<br><br>mQGiBEnnWD4RBACt9/h4v9xnnGDou13y3dvOx6/t43LPPIxeJ8eX9WB+8LLuROSV <br>lFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw7<br>8tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMD <br>u4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0Z <br>wNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq <br>/HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5<br>jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4<br>MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9<br>b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJv <br>aWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5k <br>cm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX <br>gAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI <br>2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAl <br>QN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806Up <br>hisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbk <br>C2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMX <br>LWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+<br>OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/M <br>pK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7s <br>KZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phb <br>N8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjA <br>vUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwo <br>G1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQ <br>hN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0l <br>EXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+jv2QSTlrx4KLM=<br>=Wi5D <br>-----END PGP PUBLIC KEY BLOCK-----<br></pre>
-<span><br><h2>
-Building the code</h2>
-<span>To build the files, runmakefrom within your working directory:</span>
-<br><span>$ cd ~/mydroid</span>
-<span><br>$ make</span>
-<br></span>
-<p>If your build fails, complaining about a missing "run-java-tool", try setting the ANDROID_JAVA_HOME env var to $JAVA_HOME before making.E.g.,</p>
-<p>$ export ANDROID_JAVA_HOME=$JAVA_HOME</p>
-<h2>
-Using an IDE</h2>
-<ul><li><a href="{@docRoot}source/using-eclipse.html">Using Eclipse</a>
-for Android platform development <br></li>
-</ul>
-<h2>
-Troubleshooting</h2>
-<p><span><b>ImportError: No module na</b>
-<span><b>med</b>
-</span>
-<span><b>readline</b>
-</span>
-<b><br></b>
-</span>
-</p>
-<p><span>Mac users getting this should install Python 2.5.2.</span>
-</p>
-<p><span>Linux users that installed Python from source, make sure the dependencies for libreadline are installed, and rebuild Python.</span>
-</p>
-<span><h2>
-What's next?</h2>
-</span>
-<span>To learn about reporting an issue and searching previously reported issues,</span>
-<span>see</span>
-<a href="{@docRoot}source/report-bugs.html">Report bugs</a>
-<span>.</span>
-<span>For information about editing the files and uploading changes to the
-code-review server, see <a href="{@docRoot}source/submit-patches.html">Contribute</a>
-.</span>
-</div>
-</div>
-</div>
+
+<div>
+ <h2>What's next?</h2>
+ <p>See <a href="{@docRoot}source/using-eclipse.html">Using Eclipse</a> for instructions on how to use an IDE for Android platform development. To learn about reporting an issue and searching previously reported issues, see <a href="{@docRoot}source/report-bugs.html">Report bugs</a>. For information about editing the files and uploading changes to the code-review server, see <a href="{@docRoot}source/submit-patches.html">Contribute</a>.
</div>
diff --git a/pdk/docs/source/git-repo.jd b/pdk/docs/source/git-repo.jd
index cf10ab7..f777e58 100644
--- a/pdk/docs/source/git-repo.jd
+++ b/pdk/docs/source/git-repo.jd
@@ -1,6 +1,7 @@
page.title=Using Repo and Git
doc.type=source
@jd:body
+<div>
<p>To work with the Android code, you will need to use both Git and Repo.<br></p>
<ul><li><i>Git</i>
is an open-source version-control system designed to handle very large projects that are distributed over multiple repositories. In the context of Android, we use Git for local operations such as local branching, commits, diffs, and edits.<br><br></li>
@@ -22,8 +23,8 @@
In most situations, you can use Git instead of Repo, or mix Repo and Git
commands to form complex commands. Using Repo for basic across-network
operations will make your work much simpler, however.
-<br></div>
-<div><div><h2>
+<br>
+<div><h2>
Task reference <br></h2>
The task list below shows a summary of how to do common Repo and Git tasks.
For complete quick-start information and examples, see <a
@@ -288,14 +289,13 @@
Getting started with the Android source code:
<ul>
- <li><a href="http://source.android.com/download">Get source</a></li>
- <li><a href="http://source.android.com/submit-patches/code-style-guide">Code Style Guide</a></li>
+ <li><a href="http://source.android.com/source/download.html">Get source</a></li>
+ <li><a href="http://source.android.com/source/code-style.html">Code Style Guide</a></li>
</ul>
Repo and Git resources:
<ul>
- <li><a href="http://source.android.com/download/using-repo#TOC-Git-and-Repo-cheatsheet">Git and Repo cheat sheet</a></li>
- <li><a href="http://source.android.com/download/using-repo">Using Repo and Git</a></li>
+ <li><a href="http://source.android.com/source/git-repo.html">Using Repo and Git</a></li>
<li>The <a href="http://book.git-scm.com/">Git Community Book</a> maintained by Scott Chacon</li>
<li><a href="http://git.or.cz/gitwiki/FrontPage">GitWiki</a></li>
<li><a href="http://www.kernel.org/pub/software/scm/git/docs/">Git Manual Page</a></li>
@@ -304,7 +304,7 @@
Documentation on specific tasks:
<ul>
- <li><a href="http://source.android.com/documentation/building-for-dream">Building for an Android Developer Phone</a></li>
+ <li><a href="http://source.android.com/source/building-dream.html">Building for an Android Developer Phone</a></li>
</ul>
-->
@@ -317,4 +317,3 @@
At intervals, you use git commit to save a snapshot of the staged files and a log message that describes the change.<br><br><i>Manifest</i>
<br>A manifest file that contains a list of repositories and a mapping of where the files from these repositories will be located within your working directory. When you synchronize your files, the files contained in the repositories that are listed in the manifest will be pulled into your working directory.</div>
</div>
-</div>
diff --git a/pdk/docs/source/index.jd b/pdk/docs/source/index.jd
index 230a0b3..a9acbf4 100644
--- a/pdk/docs/source/index.jd
+++ b/pdk/docs/source/index.jd
@@ -3,7 +3,7 @@
@jd:body
<div>
<p>Thanks for your interest in Android! Here are some ways you can get involved
-and help Google improve Android. For background on the Android project and our
+and help us improve Android. For background on the Android project and our
goals, check out the <a href="{@docRoot}about/philosophy.html">Project
Philosophy page</a>.</p>
@@ -11,7 +11,7 @@
<p>One of the easiest and most effective ways you can help improve Android is
to file bugs. For more information, visit the <a
href="{@docRoot}source/report-bugs.html">Reporting Bugs</a> page.</p>
-<p>Please note that we can't guarantee that any particular bug can be fixed in
+<p>Please note that we can't guarantee that any particular bug will be fixed in
any particular release. To see what happens to your bug once you report it,
read <a href="{@docRoot}source/life-of-a-bug.html">Life of a Bug</a>.</p>
@@ -26,8 +26,10 @@
<h2>Contribute to the Code</h2>
<p>Code is King. We'd love to review any changes you submit, so please check
-out the source, pick a bug or feature, and get coding.</p>
-<p>You can get started with by learning about the <a
+out the source, pick a bug or feature, and get coding. Note that the smaller
+and more targetted your patch submissions, the easier it will be for us to
+review them.</p>
+<p>You can get started with Android by learning about the <a
href="{@docRoot}source/life-of-a-patch.html">Life of a Patch</a>, and by
learning about <code>git</code>, <code>repo</code>, and other tools using the
links to the left. If you need help along the way, you can join our <a
diff --git a/pdk/docs/source/licenses.jd b/pdk/docs/source/licenses.jd
index 846a92a..17cebeb 100644
--- a/pdk/docs/source/licenses.jd
+++ b/pdk/docs/source/licenses.jd
@@ -4,18 +4,15 @@
<div>
<p>The Android Open Source Project uses a few <a
href="http://www.opensource.org/">open source initiative</a> approved open
-source licenses to enable availability of source code and to accept
-contributions from individuals and corporations.</p>
+source licenses for our software.</p>
<h2>Android Open Source Project license</h2>
-<p>The preferred license for the Android Open Source Project is <a
-href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. Apache 2.0
-is a commercial and open source friendly open source license. The majority of
-the Android platform is licensed under the <a
-href="http://www.apache.org/licenses/">Apache 2.0 license</a>. While the
-project will strive to adhere to the preferred license, there may be
-exceptions which will be handled on a case-by-case basis. For example, the
-Linux kernel patches are under the GPLv2 license with system exceptions, which
-can be found on <a
+<p>The preferred license for the Android Open Source Project is the <a
+href="http://www.apache.org/licenses/LICENSE-2.0">Apache Software License,
+2.0</a> ("Apache 2.0"), and the majority of the Android software is licensed
+with Apache 2.0. While the project will strive to adhere to the preferred
+license, there may be exceptions which will be handled on a case-by-case
+basis. For example, the Linux kernel patches are under the GPLv2 license with
+system exceptions, which can be found on <a
href="http://www.kernel.org/pub/linux/kernel/COPYING">kernel.org</a>.
</p>
<h2>Contributor License Grants</h2>
@@ -25,15 +22,15 @@
href="{@docRoot}source/cla-individual.html">Individual
Contributor License Grant</a>. The grant can be executed online through the <a
href="https://review.source.android.com/#settings,agreements">code review
-tool</a>. The agreement clearly defines the terms under which intellectual
-property has been contributed to the Android Open Source Project.This license
+tool</a>. The grant clearly defines the terms under which intellectual
+property has been contributed to the Android Open Source Project. This license
is for your protection as a contributor as well as the protection of the
project; it does not change your rights to use your own contributions for any
other purpose.</p>
<p>For a <b>corporation</b> (or other entity) that has assigned employees to
work on the Android Open Source Project, a <a
href="{@docRoot}source/cla-corporate.html">Corporate
-Contributor License Grant</a> is available. This version of the Grant allows a
+Contributor License Grant</a> is available. This version of the grant allows a
corporation to authorize contributions submitted by its designated employees
and to grant copyright and patent licenses. Note that a Corporate Contributor
License Grant does not remove the need for any developer to sign their own
diff --git a/pdk/docs/source/life-of-a-bug.jd b/pdk/docs/source/life-of-a-bug.jd
index 1d58ae1..5d77f7a 100644
--- a/pdk/docs/source/life-of-a-bug.jd
+++ b/pdk/docs/source/life-of-a-bug.jd
@@ -57,7 +57,7 @@
which is considered the "master" copy. (For instance, Google maintains one
such private issue tracker, intended primarily for bugs which contain
sensitive information which can't be revealed publicly.)</p></li>
-<li><b>Assigned</b><li>Like <code>Unassigned</code>, but the bug has been
+<li><b>Assigned</b><p>Like <code>Unassigned</code>, but the bug has been
actually assigned to a specific contributor to fix.</p></li>
</ul>
<p>Typically, a given bug will start in <code>Unassigned</code>, where it
@@ -77,8 +77,8 @@
<li><b>Spam</b><p>A kind soul sent us some delicious pork products, that we,
regrettably, do not want.</p></li>
<li><b>Question</b><p>Someone mistook the issue tracker for a help forum.
-(This is not as uncommon as one might assume: many users whose native language
-isn't English can make this mistake.)</p></li>
+(This is not as uncommon as you might think: many users whose native language
+isn't English misunderstand the site and make this mistake.)</p></li>
<li><b>Unreproducible</b><p>An AOSP contributor attempted to reproduce the
behavior described, and was unable to do so. This sometimes means that the bug
is legitimate but simply rare or difficult to reproduce, and sometimes means
diff --git a/pdk/docs/source/overview-1.0.jd b/pdk/docs/source/overview-1.0.jd
deleted file mode 100644
index e1b5cd6..0000000
--- a/pdk/docs/source/overview-1.0.jd
+++ /dev/null
@@ -1,157 +0,0 @@
-page.title=Android 1.0 Features
-doc.type=source
-@jd:body
-<div><div><div><div>This page provides a high-level overview of Android 1.0
-features. To see the code itself, you can either use the <a href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can <a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine.<br><br><b>Applications</b>
-<br><br>The Android platform comes with a variety of applications written using the Java programming language:<br><ul><li><i>Home</i>
-displays applications, widgets, and shortcuts. It also supports customizable wall paper.
-</li>
-<li><i>Phone</i>
-supports regular telephony functions as well as call controls, conference calls, supplementary services, and easy integration with <i>Contacts</i>
-.<br></li>
-<li><i>Web Browser</i>
-is a fully featured WebKit-based browser that supports HTML and XHTML.
-</li>
-<li><i>Email</i>
-provides access to email servers commonly found on the Internet and supports POP3, IMAP4, and SMTP.
-</li>
-<li><i>Media Player</i>
-enables managing, importing, and playing back content that has been encoded in various forms.<br></li>
-<li><i>Alarm Clock, Calculator, Calendar, Camera, Contacts, IM, MMS, Settings,</i>
-<i>Voice Dialer</i>
-, and many other applications are also included in this release.<br></li>
-</ul>
-<b>Application framework</b>
-<br><br></div>
-<div>The Android Application Framework has been designed to provide a rich set of APIs for third-party application developers. For more information, visit the <a href="http://developer.android.com/guide/index.html">Android SDK developer guide</a>
-.<b><br></b>
-</div>
-<div></div>
-<div><b>Android runtime</b>
-<b><br><br></b>
-Android applications run on Dalvik, a custom virtual machine (VM) designed for embedded use. The Dalvik VM runs dex executable files, which are typically compiled from source code written in Java.<br><br></div>
-<div>The dex executable format is designed to have these characteristics:<br><ul><li>Efficient on-device storage.
-</li>
-<li>Efficient runtime memory usage.
-</li>
-<li>Ease of interpretation.<br></li>
-</ul>
-Dalvik has the following runtime characteristics:
-<ul><li>Efficient support for multiple concurrent VM processes, including amortized initialization and heavily shared memory.
-</li>
-<li>Optimized interpreter.
-</li>
-<li>Efficient linkage to low-level native code.
-</li>
-<li>A familiar and rich set of core library functionality. For a complete list of supported libraries, see <a href="http://developer.android.com/reference/packages.html">http://developer.android.com/reference/packages.html</a>
-.
-</li>
-<li>Enhanced JDWP support, enabling easier debugging of multiple processes simultaneously.
-</li>
-<li>JNI support.
-</li>
-</ul>
-<b>Native libraries <br></b>
-<br>The Android platform makes use of many native libraries, including:<br><ul><li><i>Bionic</i>
-, a custom libc implementation optimized for embedded systems.
-</li>
-<li>Graphics libraries for 2D and 3D (OpenGL ES 1.0) graphics support.<br></li>
-<li>openCore to provide the bulk of Android's multimedia capability. It includes support for network streaming (HTTP and RTSP), as well as most of the codecs and media file parsers used by the system.<br></li>
-<li>sqlite to support having a lightweight transactional data store.
-</li>
-<li>WebKit library to power Android's WebKit based full web browser.<br></li>
-</ul>
-<br><b>System software</b>
-<b><br></b>
-<br></div>
-<div>About Android's operating system:
-<ul><li>Based on Linux 2.6.25 for ARM.<br></li>
-<li>Platform currently expects ARM V5T or better architecture. Support for earlier architectures could be added, but CPUs without an MMU would be difficult to support.
-</li>
-<li>A set of kernel enhancements are provided to support Android. The patches include alarm, ashmem, binder, power management, low memory killer, kernel degugger, and logger <b>.<br></b>
-</li>
-<li>While the platform is designed to be chipset agnostic, and will run on virtually any ARM-based Linux kernel environment, version 1.0 of the platform has been tested and verified on the MSM 7K chipsets <b>.</b>
-Over time we expect to see support for other major chipsets.
-Kernel patches for MSM based chipsets are also available.
-</li>
-<li>FAT32 file system is supported.
-</li>
-<li>Support for TCP/IP (TCP, UDP, etc).
-</li>
-</ul>
-</div>
-<div>A minimal reference bootloader for the supported chipset is provided. It is capable of booting Linux from RAM, debugger, and NAND Flash.<br></div>
-<div><br>About Android's support for debugging:<br><ul><li>Debugging native code is supported via GDB (GNU Project Debugger) over USB.
-</li>
-<li>Debugging managed code is supported via any JDWP-compatible debugger over USB.
-</li>
-<li>Logging and crash logs supported for debugging.
-</li>
-</ul>
-<b>Supported hardware <br></b>
-<ul><li>The platform will run on almost on any ARM based Linux kernel environment.
-</li>
-<li>The platform requires a minimum of 128 MB of RAM and 256 MB ofFlash memory. AnOEM may want to support more Flash memory to make it possible to download more third-party applications to user devices.<br></li>
-<li>The platform will interface with a baseband radio stack provided externally via a Radio Interface Layer (RIL).
-</li>
-<li>802.11 b/g Wi-Fi
-</li>
-<li>Standard USB interface, including USB 2.0
-</li>
-<li>Bluetooth 2.0 EDR (Enhanced Data Rate)
-</li>
-<li>Camera for still and video capture
-</li>
-<li>Removable storage
-</li>
-</ul>
-<b>Supported display</b>
-<br><ul><li>HVGA resolution <br></li>
-<li>16 bit color depth <br></li>
-<li>Landscape and portrait orientation, including dynamic runtime switching
-</li>
-<li>Finger-based touchscreen navigation
-</li>
-</ul>
-<b>Supported keypads and buttons</b>
-<br><ul><li>QWERTY
-</li>
-<li>5-way navigation
-</li>
-<li>Hardware buttons: Send, End, Home, Back, Menu</li>
-<li>Power button
-</li>
-<li>Volume keys (up and down)
-</li>
-<li>Camera trigger button, including detection for both partial press (to focus) and full press (to actually take a picture)
-</li>
-</ul>
-<b>Supported audio outputs</b>
-<br><ul><li>Audio output via the headphone jack (mono and stereo)
-</li>
-<li>64 kbps Bluetooth audio supported</li>
-</ul>
-<b>Supported notifications</b>
-<br><ul><li>LEDs
-</li>
-<li>Vibration
-</li>
-</ul>
-<b>Supported radio and telephony features <br></b>
-<ul><li>GPRS, EDGE, UMTS, HSDPA
-</li>
-<li>International roaming, SMS, MMS <br></li>
-<li>Emergency call support <br></li>
-<li>Supplementary Services for Telephony, for example call waiting and conference calling <br></li>
-<li>Unstructured Supplementary Service Data (USSD)
-</li>
-<li>Reference Radio Interface Layer (RIL)
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/overview-1.5.jd b/pdk/docs/source/overview-1.5.jd
deleted file mode 100644
index dd74874..0000000
--- a/pdk/docs/source/overview-1.5.jd
+++ /dev/null
@@ -1,198 +0,0 @@
-page.title=Android 1.5 Features
-doc.type=source
-@jd:body
-<h3><b>Release features - Android 1.5</b>
-</h3>
-<div><div><div><div><b>Previous release highlights</b>
-:<a href="{@docRoot}source/overview-1.0.html">Android 1.0</a>
-<br><br>This page provides a high-level overview of the new features added to
-Android 1.5. To see the code itself, you can either use the<a href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can<a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine. You can use<i>repo init -u</i>
-git://android.git.kernel.org/platform/manifest.git<i>-b android-1.5</i>
-to download the source code for Android 1.5.<br><br><b>User interface refinements:</b>
-<br><ul><li>System-wide:
-<ul><li>Refinement of all core UI elements
-</li>
-<li>Animated window transitions (off by default)
-</li>
-<li>Accelerometer-based application rotations
-</li>
-</ul>
-</li>
-<li>UI polish for:
-<ul><li>In-call experience
-</li>
-<li>Contacts, Call log, and Favorites
-</li>
-<li>SMS MMS
-</li>
-<li>Browser
-</li>
-<li>Calendar
-</li>
-<li>Email
-</li>
-<li>Camera Gallery
-</li>
-<li>Application management
-</li>
-</ul>
-</li>
-</ul>
-<div><b><br>Performance improvements:</b>
-<br></div>
-<ul><li>Faster Camera start-up and image capture
-</li>
-<li>Much faster acquisition of GPS location (powered by SUPL AGPS)
-</li>
-<li>Smoother page scrolling in Browser
-</li>
-</ul>
-<br><b>Applications</b>
-<br><ul><li>Camera Gallery
-</li>
-<ul><li>Video recording
-</li>
-<li>Video playback (MPEG-4 3GP formats)
-</li>
-</ul>
-<li>Browser
-</li>
-<ul><li>Updated with latest Webkit browser Squirrelfish Javascript engines
-</li>
-<li>Copy 'n paste in browser
-</li>
-<li>Search within a page
-</li>
-<li>User-selectable text-encoding
-</li>
-<li>UI changes include:
-</li>
-<ul><li>Unified Go and Search box
-</li>
-<li>Tabbed bookmarks/history/most-visited screen
-</li>
-</ul>
-</ul>
-<li>Contacts
-</li>
-<ul><li>Shows user picture for Favorites
-</li>
-<li>Specific date/time stamp for events in call log
-</li>
-<li>One-touch access to a contact card from call log event
-</li>
-</ul>
-</ul>
-<b><br>Application framework</b>
-<br><br></div>
-<div><ul><li>On-screen soft keyboard
-</li>
-<ul><li>Works in both portrait and landscape orientation
-</li>
-<li>Support for user installation of 3rd party keyboards
-</li>
-<li>User dictionary for custom words
-</li>
-</ul>
-<li>Home screen
-</li>
-<ul><li>Widgets
-</li>
-<ul><li>Bundled home screen widgets include: analog clock, calendar, music player, picture frame, and search
-</li>
-</ul>
-<li>Live folders
-</li>
-</ul>
-<li>UI framework
-</li>
-<ul><li>Framework for easier background/UI thread interaction
-</li>
-<li>New SlidingDrawer widget
-</li>
-<li>Horizontal ScrollView widget
-</li>
-</ul>
-<li>Home Screen framework
-</li>
-<ul><li>APIs for creating secure home screen widgets
-</li>
-<li>APIs for populating live folders with custom content
-</li>
-</ul>
-<li>Media framework
-</li>
-<ul><li>Raw audio recording and playback APIs
-</li>
-<li>Interactive MIDI playback engine
-</li>
-<li>Video recording APIs for developers (3GP format)
-</li>
-<li>Video and photo sharing Intents
-</li>
-<li>Media search Intent
-</li>
-</ul>
-<li>Input Method framework
-</li>
-<ul><li>Text prediction engine
-</li>
-<li>Ability to provide downloadable IMEs to users
-</li>
-</ul>
-<li>Speech recognition framework
-</li>
-<ul><li>Support for using speech recognition libraries via Intent
-</li>
-</ul>
-<li>Misc API additions
-</li>
-<ul><li>LocationManager - Applications can get location change updates via Intent
-</li>
-<li>WebView - Touch start/end/move/cancel DOM event support
-</li>
-<li>SensorManager - redesigned sensor APIs
-</li>
-<li>GLSurfaceView - convenience framework for creating OpenGL applications
-</li>
-<li>Broadcast Intent for app update install succeeded - for smoother app upgrade experience
-</li>
-</ul>
-</ul>
-</div>
-<div></div>
-<div><br><b>System software</b>
-<br><br></div>
-<ul><li>New Linux kernel (version 2.6.27)
-</li>
-<li>SD card filesystem auto-checking and repair
-</li>
-<li>SIM Application Toolkit 1.0
-</li>
-</ul>
-<div><b><br>Supported hardware<br></b>
-<ul><li>Bluetooth</li>
-<ul><li>Stereo Bluetooth support (A2DP and AVCRP profiles)
-</li>
-<li>Auto-pairing
-</li>
-<li>Improved handsfree experience
-</li>
-</ul>
-</ul>
-<br><b>Developer tools</b>
-<br></div>
-<div><ul><li>Support for multiple versions of Android in a single SDK installation
-</li>
-<li>Improved JUnit support in ADT
-</li>
-<li>Easier application performance profiling
-</li>
-</ul>
-</div>
-</div>
-</div>
-</div>
diff --git a/pdk/docs/source/overview.jd b/pdk/docs/source/overview.jd
index 2763c52..5a31018 100644
--- a/pdk/docs/source/overview.jd
+++ b/pdk/docs/source/overview.jd
@@ -1,93 +1,36 @@
-page.title=Android 1.6 Platform Overview
+page.title=Android 2.1 Platform
doc.type=source
@jd:body
-<p>This page provides a high-level overview of the new features added to
-Android 1.6. To see the code itself, you can either use the <a
-href="http://android.git.kernel.org/">GitWeb</a>
-interface to view snapshots of the files, or you can <a
-href="{@docRoot}source/download.html">download</a>
-the source code onto your local machine. You can use <code>repo init -u
-git://android.git.kernel.org/platform/manifest.git -b android-1.6</code>
-to download the source code for Android 1.6.</p>
-<p><i>Note: platform overview information for Android 2.x has not yet been
-published, since the <a
-href="{@docRoot}compatibility/index.html">Compatibility Program</a> for
-Android 2.x has not yet launched. When the Compatibilty Definition Document
-for 2.x is released, this page will be updated to match.</i></p>
-<p>Information about older Android releases is also available:<ul>
-<li><a href="{@docRoot}source/overview-1.5.html">Android 1.5 Platform Overview</a></li>
-<li><a href="{@docRoot}source/overview-1.0.html">Android 1.0 Platform Overview</a></li>
-</ul></p>
-<h2>User interface refinements</h2>
-<h3>Quick Search Box for Android </h3>
-<p>Android 1.6 includes a redesigned search framework that provides a quick, effective, and consistent way for users to search across multiple sources—such as browser bookmarks history, contacts, and the web—directly from the home screen.
-</p>
-<p><br></p>
-<p>The system constantly learns which search results are more relevant based on what is clicked. So popular contacts or apps that have previously been picked will bubble up to the top when a user types the first few letters of a relevant query.
-</p>
-<p><br></p>
-<p>The search framework also provides developers a way to easily expose relevant content from their applications in Quick Search Box.
-</p>
-<h3>Camera, Camcorder, and Gallery </h3>
-<p>An updated user interface provides an integrated camera, camcorder, and gallery experience. Users can quickly toggle between still and video capture modes. Additionally, the gallery enables users to select multiple photos for deletion.<br></p>
-<p><br></p>
-<p>Android 1.6 also provides a much faster camera experience. Compared to the previous release, launching the camera is now 39% faster, and there is a 28% improvement in the time from completing one shot to the next.
-</p>
-<h3>VPN, 802.1x </h3>
-<p>A new Virtual Private Network (VPN) control panel in Settings allows users to configure and connect to the following types of VPNs:
-</p>
-<ul><li>L2TP/IPSEC pre-shared key based VPN
- </li>
-<li>L2TP/IPsec certificate based VPN
- </li>
-<li>L2TP only VPN
- </li>
-<li>PPTP only VPN
- </li>
-</ul>
-<h3>Battery usage indicator </h3>
-<p>A new battery usage screen lets users see which apps and services are consuming battery power. If the user determines that a particular service or application is using too much power, they can take action to save the battery by adjusting settings, stopping the application, or uninstalling the application.
-</p>
-<h3>Accessibility </h3>
-<p>Users will be able to download new accessibility services built on the new accessibility framework and enable them in Settings.
-</p>
-<h2>New Platform Technologies </h2>
-<h3>Expanded Search Framework </h3>
-<p>The Android search framework has been redesigned and expanded to provide third-party applications the opportunity to surface content from their applications in Quick Search Box, the global search tool. To do this, developers will need to make their app "searchable" and provide suggestions in response to user queries. To enable application search suggestions, users simply select each application from which they'd like to receive suggestions, under Searchable items in the Search settings.
-</p>
-<h3>Text-to-speech engine</h3>
-<p>Android 1.6 features a multi-lingual speech synthesis engine called Pico. It allows any Android application to "speak" a string of text with an accent that matches the language. The engine supports the following languages: English (American and British accents), French, Italian, German and Spanish. If you're using a T-Mobile G1 or Dream device, you'll need to download the SpeechSynthesis Data Installer from Android Market, which includes the "voices" needed by the text-to-speech engine.
-</p>
-<h3>Gestures </h3>
-<p>A new gestures framework provides application developers with a framework for creating, storing, loading, and recognizing gestures and associating them with specific actions.
-</p>
-<p>Developers can use the new GestureBuilder tool included in the Android 1.6 SDK to generate libraries of gestures to include with their application.
-</p>
-<h3>Accessibility </h3>
-<p>Android 1.6 provides a new accessibility framework. With this framework, developers can create accessibility plugins that respond to user input, such as making a sound when a new window is shown, vibrating when navigating to the top of a list, and providing spoken feedback.
-</p>
-<h3>Expanded support for screen densities and resolutions </h3>
-<p>Android 1.6 adds screen support that enables applications to be rendered properly on different display resolutions and densities. Developers can also specify the types of screens supported by their application.
-</p>
-<h3>Telephony support for CDMA </h3>
-<p>Android 1.6 includes support for CDMA in the telephony stack.
-</p>
-<h3>New version of OpenCore </h3>
-<p>Android 1.6 includes the updated OpenCore 2 media engine, which has:
-</p>
-<ul><li>Support for OpenMAX encoders
- </li>
-<li>Support for additional audio codecs in AuthorEngine
- </li>
-<li>Improved buffering model supports shared buffers allocated in the decoder
- </li>
-</ul>
-<h3>2.6.29 Linux kernel </h3>
-<p>Android 1.6 upgrades the Linux kernel from 2.6.27 to 2.6.29.
-</p>
-<h2>New Framework APIs</h2>
-<p>For a detailed overview of new APIs, see the <a
-href="http://developer.android.com/sdk/android-1.6.html#api-changes">Version
-Notes</a>. For a complete report of all API changes, see the <a
-href="http://developer.android.com/sdk/api_diff/4/changes.html">API
-Differences Report</a>.</p>
+<p>Our sister site, <a
+href="http://developer.android.com/">http://developer.android.com/</a>,
+includes feature overviews of the various Android platform versions.
+The links below will take you to developer.android.com where you can view this
+information.</p>
+<p>The links below will navigate you away from this site.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.3-highlights.html">Android 2.3</a></h3>
+<p>Android 2.3 corresponded to the "Gingerbread" milestone branch, and has an API level of 9.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.2-highlights.html">Android 2.2</a></h3>
+<p>Android 2.2 corresponded to the "FroYo" milestone branch, and has an API level of 8.</p>
+<h3><a href="http://developer.android.com/sdk/android-2.0-highlights.html">Android 2.1</a></h3>
+<p>Android 2.1 corresponded to the "Eclair" milestone branch, and has an API level of
+7.</p>
+<p>The Eclair branch was also used for 2.0 and 2.0.1; however, both of those
+releases were quickly obsoleted by the version 2.1 Eclair release. As Android
+2.1 includes key bug fixes and improvements not present in 2.0/2.0.1, only
+Android 2.1 should be used for new devices. As there is no compatibility
+program for 2.0 or 2.0.1, the officially compatible Eclair-based release is Android
+2.1. (The linked document refers to Android 2.0, because there were
+no new platform features added in 2.1.)</p>
+<h3><a href="http://developer.android.com/sdk/android-1.6-highlights.html">Android 1.6</a></h3>
+<p>Android 1.6 corresponded to the "Donut" milestone branch, and has an API level of
+4.</p>
+<h3><a href="http://developer.android.com/sdk/android-1.5-highlights.html">Android 1.5</a></h3>
+<p>Android 1.5 corresponded to the "Cupcake" milestone branch, and has an API
+level of 3.</p>
+<h3><a href="http://developer.android.com/sdk/android-1.1.html">Android 1.1</a></h3>
+<p>Android 1.1 has an API level of 2. Android 1.1 was known as
+"Petit Four" internally, though this name was not used officially.</p>
+<h3>Android 1.0</h3>
+<p>was the first release of Android, and has an API
+level of 1. Since it was the first released version of Android, no platform
+highlights were prepared for this release.</p>
diff --git a/pdk/docs/source/report-bugs.jd b/pdk/docs/source/report-bugs.jd
index 138080d..a6e56c6 100644
--- a/pdk/docs/source/report-bugs.jd
+++ b/pdk/docs/source/report-bugs.jd
@@ -77,7 +77,7 @@
public class TestObjectNull extends Activity {
/** Called when the activity is first created. */
- @Override
+ @Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
diff --git a/pdk/docs/source/roles.jd b/pdk/docs/source/roles.jd
index 451c821..f4fb891 100644
--- a/pdk/docs/source/roles.jd
+++ b/pdk/docs/source/roles.jd
@@ -15,22 +15,22 @@
<h2>Contributor</h2>
<p>A "Contributor" is anyone making contributions to the AOSP source code,
-including both employees of Google or other companies, as well as
-external developers who are contributing to Android on their own behalf.
-There is no distinction between Contributors who are employed by
-Google, and those who are not: all engineers use the same git/gerrit tools,
-follow the same code review process, and are subject to the same requirements
-on code style and so on.</p>
+including both employees of Google or other companies, as well as external
+developers who are contributing to Android on their own behalf. There is no
+distinction between Contributors who are employed by Google, and those who are
+not: all engineers use the same tools (<code>git</code>, <code>repo</code>,
+and <code>gerrit</code>), follow the same code review process, and are subject
+to the same requirements on code style and so on.</p>
<p/>
<h2>Developer</h2>
<p>A "Developer" is an engineer writing applications that run on Android
devices. There is, of course, no difference in skillset between a "Developer"
-and a "Contributor"; AOSP simply uses "Developer" to help identify our audience.
-Since the key purpose of Android is to cultivate an open development platform,
-"Developers" are one of the key customers of the Android platform. As such, we
-talk about them a lot, though this isn't technically a separate role in the
-AOSP <i>per se.</i></p>
+and a "Contributor", but AOSP uses "Developer" to distinguish between
+engineers using the platform and those contributing to it. Developers are
+(along with end users) the "customers" of the platform that the Contributors
+create. As such, we talk about Developers a lot, though this isn't technically
+a separate role in the AOSP <i>per se.</i></p>
<p/>
<h2>Verifier</h2>
@@ -62,12 +62,12 @@
releases.</li>
<li>Designate Verifiers and Approvers for submitted patches.</li>
<li>Be fair and unbiased while reviewing changes. Accept or reject patches
- based on technical merit and alignment with the Android platform.</li>
+ based on technical merit and alignment with the Android strategy.</li>
<li>Review changes in a timely manner and make best efforts to communicate
when changes are not accepted.</li>
<li>Optionally maintain a web site for the project for information and
documents specific to the project.</li>
<li>Act as a facilitator in resolving technical conflicts.</li>
- <li>Be the public face for the project and the go-to person for questions
+ <li>Be a public face for the project and the go-to person for questions
related to the project.</li>
</ul>
diff --git a/pdk/docs/source/submit-patches.jd b/pdk/docs/source/submit-patches.jd
index 2b7bae1..9e7d9df 100644
--- a/pdk/docs/source/submit-patches.jd
+++ b/pdk/docs/source/submit-patches.jd
@@ -1,6 +1,7 @@
page.title=Android Contributors' Workflow
doc.type=source
@jd:body
+<div>
<br>This page describes how to record changes to the Android files on your local client, upload those changes to the code-review server, and use Gerrit to track changes.<br><h2>
Prerequisites</h2>
Before you follow the instructions on this page, you will need to set up your
@@ -14,6 +15,9 @@
Open Source community, see <a href="{@docRoot}source/roles.html">Project roles</a>.</li>
<li>If you plan to contribute code to the Android platform, be sure to read
the <a href="{@docRoot}source/licenses.html">AOSP's licensing information</a>.</li>
+<li>Note that changes to some of the upstream projects used by Android should be
+made directly to that project, as described in
+<a href="#upstream-projects">Upstream Projects</a>.
</ul>
<h2>
Working with the code</h2>
@@ -129,8 +133,8 @@
</ul>
<h3>
Viewing diffs and comments</h3>
-To open the details of the change within Gerrit, click on the "Id number" or "Subject" of a change. To compare the established code with the updated code, click the file name under "Side-by-side diffs."<br></div>
-<div><h3>
+To open the details of the change within Gerrit, click on the "Id number" or "Subject" of a change. To compare the established code with the updated code, click the file name under "Side-by-side diffs."<br>
+<h3>
Adding comments</h3>
Anyone in the community can use Gerrit to add inline comments to code submissions. A good comment will be relevant to the line or section of code to which it is attached in Gerrit. It might be a short and constructive suggestion about how a line of code could be improved, or it might be an explanation from the author about why the code makes sense the way it is.<br><br>To add an inline comment, double-click the relevant line of the code and write your comment in the text box that opens. When you click Save, only you can see your comment.<br><br>To publish your comments so that others using Gerrit will be able to see them, click the Publish Comments button. Your comments will be emailed to all relevant parties for this change, including the change owner, the patch set uploader (if different from the owner), and all current reviewers.<br><br><h3>
After a submission is approved</h3>
@@ -142,6 +146,27 @@
.<br><br><h2>
Using GitWeb to track patch histories</h2>
To view snapshots of the files that are in the public Android repositories and view file histories, use the <a href="http://android.git.kernel.org/">Android instance of GitWeb</a>
-.<br></div>
-</div>
+.<br>
+<h2><a name="upstream-projects"></a>Upstream Projects</h2>
+Android makes use of a number of other open-source projects, such as the Linux
+kernel and WebKit, as described in
+<a href="{@docRoot}source/code-lines.html">Branches & Releases</a>. For the
+upstream projects detailed below, changes should be made directly upstream. Such
+changes will be incorporated into the Android tree as part of the usual process
+of pulling these projects.
+<h3>WebKit</h3>
+All changes to the WebKit project at <code>external/webkit</code> should be made
+upstream at <a href="http://www.webkit.org">http://www.webkit.org</a>. The
+process begins by filing a WebKit bug. This bug should use <code>Android</code>
+for the <code>Platform</code> and <code>OS</code> fields only if the bug is
+specific to Android. Bugs are far more likely to receive the reviewers'
+attention once a proposed fix is added and tests are included. See
+<a href="http://webkit.org/coding/contributing.html">Contributing Code to
+WebKit</a> for details.
+<h3>V8</h3>
+All changes to the V8 project at <code>external/v8</code> should be submitted
+upstream at
+<a href="http://code.google.com/p/v8">http://code.google.com/p/v8</a>. See
+<a href="http://code.google.com/p/v8/wiki/Contributing">Contributing to V8</a>
+for details.
</div>
diff --git a/pdk/docs/source/using-eclipse.jd b/pdk/docs/source/using-eclipse.jd
index 56df713..660de11 100644
--- a/pdk/docs/source/using-eclipse.jd
+++ b/pdk/docs/source/using-eclipse.jd
@@ -95,58 +95,6 @@
<p>When you're done, the "source folder" path in the list should look like android/packages/apps/<i>YourAppName</i>
/src. Depending on which app(s) you include, you may also need to include othersrc/main/java directories under android/dalvik/libcore. Do this if you find you cannot build with the default set.
</p>
-<h4>
-Eclipse setup to work on developer tools
-</h4>
-<p>To work on Java developer tools, the principle is the same, except you specify /path/to/tool when using the option "Create project from existing source."
-</p>
-<p>Once the project is created, you need to set up the Java Build Path:
-</p>
-<ol><li>Select the project you just created.
-</li>
-<li>Project Properties
-</li>
-<li>Select "Java Build Path" from the left-hand menu.
-</li>
-<li>Choose the "Source" tab.
-</li>
-<li>Expand the single <i>toolname</i>
-/src entry.
-</li>
-<li>Double click the "Excluded: (none)" item.
-</li>
-<li>Add to the excluded (bottom) list: "MakeFile" and "resources/".
-</li>
-<li>Close the dialog.
-</li>
-<li>Back in the "Source" tab, click "Add Folder...", and add <i>toolname</i>
-/src/resources.
-</li>
-<li>Click OK.
-</li>
-</ol>
-<h4>
-Eclipse setup to work on DDMS <br></h4>
-<p>For DDMS, you will need to make a project for
-</p>
-<ol><li>development/tools/ddms/libs/ddmlib
-</li>
-<li>development/tools/ddms/libs/ddmuilib
-</li>
-<li>development/tools/ddms/app
-</li>
-</ol>
-<p>Each project will need to reference the ones before it ("ddmuilib" references "ddmlib", and "app" references both of those). To do this:
-</p>
-<ol><li>Make sure you have all 3 projects defined.
-</li>
-<li>Right click on a project, "Build Path" "Configure Build Path..."
-</li>
-<li>Choose the "Project" tab.
-</li>
-<li>Click "Add..." and check the required projects.
-</li>
-</ol>
<h2><a>Eclipse formatting</a>
</h2>
<p>You can import files in development/ide/eclipse to make Eclipse
@@ -189,15 +137,6 @@
<pre>Ctrl-Shift-o = Organize imports <br>Ctrl-Shift-t = load class by name <br>Ctrl-Shift-r = load non-class resource by name <br>Ctrl-1 = quick fix <br>Ctrl-e = Recently viewed files <br>Ctrl-space = auto complete <br>Shift-Alt-r = refactor:rename <br>Shift-Alt-v = refactor:move <br></pre>
-<h2><a>Useful Plugins</a>
-</h2>
-<p>Eclipse has a plugin architecture that enables third parties to extend the IDE. Here are some plugins that make Eclipse easier to use for writing Android software:
-</p>
-
-<ul><li><a href="http://andrei.gmxhome.de/anyedit/">AnyEdit</a>
-- automatically fix whitespace issues when saving files. Can convert tabs to spaces, strip blanks at end-of-line, and ensure the last line of the file has an end-of-line character.
-</li>
-</ul>
<h2><a>"Eclipse is not working correctly, what should I do?"</a>
</h2>
<p>Make sure:
diff --git a/tools/monkeyrunner/etc/Android.mk b/pdk/micro-httpd.py
similarity index 66%
rename from tools/monkeyrunner/etc/Android.mk
rename to pdk/micro-httpd.py
index 2d757fd..96e4000 100644
--- a/tools/monkeyrunner/etc/Android.mk
+++ b/pdk/micro-httpd.py
@@ -1,5 +1,4 @@
-#
-# Copyright (C) 2009 The Android Open Source Project
+# Copyright (C) 2010 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.
@@ -12,9 +11,9 @@
# 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_PREBUILT_EXECUTABLES := monkeyrunner
-include $(BUILD_HOST_PREBUILT)
+import SimpleHTTPServer, SocketServer, os
+PORT = int(os.environ.get('HTTP_PORT', 8080))
+Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
+httpd = SocketServer.TCPServer(("", PORT), Handler)
+httpd.serve_forever()
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 7adf48d..e88512f 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -524,7 +524,6 @@
<string name="linear_layout_8_right">Right</string>
<string name="linear_layout_10_from">From:</string>
<string name="linear_layout_10_to">To:</string>
- <string name="list_7_nothing">Nothing\u2026</string>
<string name="radio_group_snack">Snack</string>
<string name="radio_group_selection">"You have selected: "</string>
<string name="radio_group_none">(none)</string>
@@ -948,8 +947,8 @@
<!-- ============================ -->
<string name="sms_warning">
- WARNING: this demo can send actual text messages (one at a time), so be sure to
- test with the Android emulator or have a text messaging plan with your carrier.
+ WARNING: this demo can send actual text messages (one at a time), so be sure to
+ test with the Android emulator or have a text messaging plan with your carrier.
</string>
<string name="sms_enable_receiver">Enable SMS broadcast receiver</string>
<string name="sms_recipient_label">Recipient #</string>
@@ -959,4 +958,3 @@
<string name="reply">Reply</string>
<string name="dismiss">Dismiss</string>
</resources>
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
index 78b1fd7..39f24b6 100644
--- a/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
+++ b/samples/ApiDemos/src/com/example/android/apis/ApiDemos.java
@@ -52,8 +52,8 @@
getListView().setTextFilterEnabled(true);
}
- protected List getData(String prefix) {
- List<Map> myData = new ArrayList<Map>();
+ protected List<Map<String, Object>> getData(String prefix) {
+ List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
@@ -107,10 +107,11 @@
return myData;
}
- private final static Comparator<Map> sDisplayNameComparator = new Comparator<Map>() {
+ private final static Comparator<Map<String, Object>> sDisplayNameComparator =
+ new Comparator<Map<String, Object>>() {
private final Collator collator = Collator.getInstance();
- public int compare(Map map1, Map map2) {
+ public int compare(Map<String, Object> map1, Map<String, Object> map2) {
return collator.compare(map1.get("title"), map2.get("title"));
}
};
@@ -128,7 +129,7 @@
return result;
}
- protected void addItem(List<Map> data, String name, Intent intent) {
+ protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
Map<String, Object> temp = new HashMap<String, Object>();
temp.put("title", name);
temp.put("intent", intent);
@@ -136,11 +137,11 @@
}
@Override
+ @SuppressWarnings("unchecked")
protected void onListItemClick(ListView l, View v, int position, long id) {
- Map map = (Map) l.getItemAtPosition(position);
+ Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position);
Intent intent = (Intent) map.get("intent");
startActivity(intent);
}
-
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
index 90831f5..5ba41c4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/Animation.java
@@ -22,7 +22,6 @@
import com.example.android.apis.view.Controls1;
import android.app.Activity;
-import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
index bb843e5..d5b3deb 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilter.java
@@ -20,8 +20,6 @@
// class is in a sub-package.
import android.app.Activity;
import android.content.ComponentName;
-import android.content.Context;
-import android.os.RemoteException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@@ -29,7 +27,6 @@
import com.example.android.apis.R;
-
/**
* Front-end for launching {@link ContactsFilterInstrumentation} example
* instrumentation class.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
index 04bb671..6895363 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ContactsFilterInstrumentation.java
@@ -23,8 +23,6 @@
import android.os.Bundle;
import android.util.Log;
-import java.util.Map;
-
/**
* This is an example implementation of the {@link android.app.Instrumentation}
* class, allowing you to run tests against application code. The
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java b/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
index 35bdf13..494a2ea 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/DefaultValues.java
@@ -19,7 +19,6 @@
import com.example.android.apis.ApiDemosApplication;
import com.example.android.apis.R;
-import android.app.Application;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
index c7a2dfb..7e061ed 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
@@ -49,9 +49,9 @@
static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
// BEGIN_INCLUDE(foreground_compatibility)
- private static final Class[] mStartForegroundSignature = new Class[] {
+ private static final Class<?>[] mStartForegroundSignature = new Class[] {
int.class, Notification.class};
- private static final Class[] mStopForegroundSignature = new Class[] {
+ private static final Class<?>[] mStopForegroundSignature = new Class[] {
boolean.class};
private NotificationManager mNM;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
index 1bb26e9..0e4b66e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalSample.java
@@ -20,8 +20,6 @@
// class is in a sub-package.
import android.app.Activity;
import android.content.ComponentName;
-import android.content.Context;
-import android.os.RemoteException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@@ -29,7 +27,6 @@
import com.example.android.apis.R;
-
/**
* Front-end for launching {@link LocalSampleInstrumentation} example
* instrumentation class.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
index e0f6163..aabfec3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalSampleInstrumentation.java
@@ -23,8 +23,6 @@
import android.os.Bundle;
import android.util.Log;
-import java.util.Map;
-
/**
* This is an example implementation of the {@link android.app.Instrumentation}
* class demonstrating instrumentation against one of this application's sample
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
index 859969c..0c7c108 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java
@@ -45,6 +45,10 @@
public class LocalService extends Service {
private NotificationManager mNM;
+ // Unique Identification Number for the Notification.
+ // We use it on Notification start, and to cancel it.
+ private int NOTIFICATION = R.string.local_service_started;
+
/**
* Class for clients to access. Because we know this service always
* runs in the same process as its clients, we don't need to deal with
@@ -75,7 +79,7 @@
@Override
public void onDestroy() {
// Cancel the persistent notification.
- mNM.cancel(R.string.local_service_started);
+ mNM.cancel(NOTIFICATION);
// Tell the user we stopped.
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
@@ -110,8 +114,7 @@
text, contentIntent);
// Send the notification.
- // We use a layout id because it is a unique number. We use it later to cancel.
- mNM.notify(R.string.local_service_started, notification);
+ mNM.notify(NOTIFICATION, notification);
}
}
//END_INCLUDE(service)
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java b/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
index a6c20ea..25b5d56 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotificationDisplay.java
@@ -24,14 +24,11 @@
import android.app.NotificationManager;
import android.content.Intent;
import android.os.Bundle;
-import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
-import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-
/**
* Activity used by StatusBarNotification to show the notification to the user.
*/
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
index a0de699..b8b4e3f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingController.java
@@ -21,14 +21,12 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
-
/**
* Controller to start and stop a service. The serivce will update a status bar
* notification every 5 seconds for a minute.
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
index e580978..3b8139f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/NotifyingService.java
@@ -30,7 +30,6 @@
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
-import android.widget.RemoteViews;
/**
* This is an example of service that will update its status bar balloon
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
index 23461c6..63bbac2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/PreferencesFromXml.java
@@ -18,9 +18,7 @@
import com.example.android.apis.R;
-import android.content.SharedPreferences;
import android.os.Bundle;
-import android.preference.Preference;
import android.preference.PreferenceActivity;
public class PreferencesFromXml extends PreferenceActivity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java b/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java
index 1ee5742..004e568 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/QuickContactsDemo.java
@@ -75,8 +75,6 @@
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ContactListItemCache cache = (ContactListItemCache) view.getTag();
- TextView nameView = cache.nameView;
- QuickContactBadge photoView = cache.photoView;
// Set the name
cursor.copyStringToBuffer(SUMMARY_NAME_COLUMN_INDEX, cache.nameBuffer);
int size = cache.nameBuffer.sizeCopied;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java b/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
index 4e248b9..22ae7f4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ReceiveResult.java
@@ -18,8 +18,6 @@
// Need the following import to get access to the app resources, since this
// class is in a sub-package.
-import java.util.Map;
-
import com.example.android.apis.R;
import android.app.Activity;
@@ -31,8 +29,6 @@
import android.widget.Button;
import android.widget.TextView;
-import java.util.Map;
-
/**
* Shows how an activity can send data to its launching activity when done.y.
* <p>This can be used, for example, to implement a dialog alowing the user to
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java b/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
index 982317c..c96e1bb 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RedirectGetter.java
@@ -32,8 +32,11 @@
*/
public class RedirectGetter extends Activity
{
+ private String mTextPref;
+ private TextView mText;
+
@Override
- protected void onCreate(Bundle savedInstanceState)
+ protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
@@ -45,9 +48,12 @@
// The text being set.
mText = (TextView)findViewById(R.id.text);
+
+ // Display the stored values, or if not stored initialize with an empty String
+ loadPrefs();
}
- private final boolean loadPrefs()
+ private final void loadPrefs()
{
// Retrieve the current redirect values.
// NOTE: because this preference is shared between multiple
@@ -58,10 +64,9 @@
mTextPref = preferences.getString("text", null);
if (mTextPref != null) {
mText.setText(mTextPref);
- return true;
+ } else {
+ mText.setText("");
}
-
- return false;
}
private OnClickListener mApplyListener = new OnClickListener()
@@ -79,8 +84,4 @@
finish();
}
};
-
- private String mTextPref;
- TextView mText;
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java
index 8630b1c..f3d4ffb 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/SetWallpaperActivity.java
@@ -29,7 +29,6 @@
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
-import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java b/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java
index 8d7f5a1..7b5eea2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/WallpaperActivity.java
@@ -22,7 +22,6 @@
import android.app.Activity;
import android.os.Bundle;
-import android.view.WindowManager;
/**
* <h3>Wallpaper Activity</h3>
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
index 8fff231..90d3450 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AlphaBitmap.java
@@ -18,15 +18,12 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
public class AlphaBitmap extends GraphicsActivity {
@@ -35,23 +32,23 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Bitmap mBitmap;
private Bitmap mBitmap2;
private Bitmap mBitmap3;
private Shader mShader;
-
+
private static void drawIntoBitmap(Bitmap bm) {
float x = bm.getWidth();
float y = bm.getHeight();
Canvas c = new Canvas(bm);
Paint p = new Paint();
p.setAntiAlias(true);
-
+
p.setAlpha(0x80);
c.drawCircle(x/2, y/2, x/2, p);
-
+
p.setAlpha(0x30);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
p.setTextSize(60);
@@ -59,28 +56,28 @@
Paint.FontMetrics fm = p.getFontMetrics();
c.drawText("Alpha", x/2, (y-fm.ascent)/2, p);
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
InputStream is = context.getResources().openRawResource(R.drawable.app_sample_code);
mBitmap = BitmapFactory.decodeStream(is);
mBitmap2 = mBitmap.extractAlpha();
mBitmap3 = Bitmap.createBitmap(200, 200, Bitmap.Config.ALPHA_8);
drawIntoBitmap(mBitmap3);
-
+
mShader = new LinearGradient(0, 0, 100, 70, new int[] {
Color.RED, Color.GREEN, Color.BLUE },
null, Shader.TileMode.MIRROR);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
Paint p = new Paint();
float y = 10;
-
+
p.setColor(Color.RED);
canvas.drawBitmap(mBitmap, 10, y, p);
y += mBitmap.getHeight() + 10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
index 279b588..330924e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawable.java
@@ -23,23 +23,23 @@
import android.view.animation.Transformation;
public class AnimateDrawable extends ProxyDrawable {
-
+
private Animation mAnimation;
private Transformation mTransformation = new Transformation();
public AnimateDrawable(Drawable target) {
super(target);
}
-
+
public AnimateDrawable(Drawable target, Animation animation) {
super(target);
mAnimation = animation;
}
-
+
public Animation getAnimation() {
return mAnimation;
}
-
+
public void setAnimation(Animation anim) {
mAnimation = anim;
}
@@ -47,11 +47,11 @@
public boolean hasStarted() {
return mAnimation != null && mAnimation.hasStarted();
}
-
+
public boolean hasEnded() {
return mAnimation == null || mAnimation.hasEnded();
}
-
+
@Override
public void draw(Canvas canvas) {
Drawable dr = getProxy();
@@ -69,4 +69,4 @@
}
}
}
-
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
index 7c9473d..0398fbf 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/AnimateDrawables.java
@@ -18,14 +18,14 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
-import android.graphics.*;
-import android.graphics.drawable.*;
-import android.view.animation.*;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
public class AnimateDrawables extends GraphicsActivity {
@@ -34,7 +34,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private AnimateDrawable mDrawable;
@@ -45,17 +45,18 @@
Drawable dr = context.getResources().getDrawable(R.drawable.beach);
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
-
+
Animation an = new TranslateAnimation(0, 100, 0, 200);
an.setDuration(2000);
an.setRepeatCount(-1);
an.initialize(10, 10, 10, 10);
-
+
mDrawable = new AnimateDrawable(dr, an);
an.startNow();
}
-
- @Override protected void onDraw(Canvas canvas) {
+
+ @Override
+ protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
mDrawable.draw(canvas);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
index ff8b38b..1bd07f9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Arcs.java
@@ -20,7 +20,6 @@
// class is in a sub-package.
//import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -33,7 +32,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint[] mPaints;
private Paint mFramePaint;
@@ -43,27 +42,27 @@
private float mStart;
private float mSweep;
private int mBigIndex;
-
+
private static final float SWEEP_INC = 2;
private static final float START_INC = 15;
-
+
public SampleView(Context context) {
super(context);
-
+
mPaints = new Paint[4];
mUseCenters = new boolean[4];
mOvals = new RectF[4];
-
+
mPaints[0] = new Paint();
mPaints[0].setAntiAlias(true);
mPaints[0].setStyle(Paint.Style.FILL);
mPaints[0].setColor(0x88FF0000);
mUseCenters[0] = false;
-
+
mPaints[1] = new Paint(mPaints[0]);
mPaints[1].setColor(0x8800FF00);
mUseCenters[1] = true;
-
+
mPaints[2] = new Paint(mPaints[0]);
mPaints[2].setStyle(Paint.Style.STROKE);
mPaints[2].setStrokeWidth(4);
@@ -73,36 +72,36 @@
mPaints[3] = new Paint(mPaints[2]);
mPaints[3].setColor(0x88888888);
mUseCenters[3] = true;
-
+
mBigOval = new RectF(40, 10, 280, 250);
-
+
mOvals[0] = new RectF( 10, 270, 70, 330);
mOvals[1] = new RectF( 90, 270, 150, 330);
mOvals[2] = new RectF(170, 270, 230, 330);
mOvals[3] = new RectF(250, 270, 310, 330);
-
+
mFramePaint = new Paint();
mFramePaint.setAntiAlias(true);
mFramePaint.setStyle(Paint.Style.STROKE);
mFramePaint.setStrokeWidth(0);
}
-
+
private void drawArcs(Canvas canvas, RectF oval, boolean useCenter,
Paint paint) {
canvas.drawRect(oval, mFramePaint);
canvas.drawArc(oval, mStart, mSweep, useCenter, paint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
drawArcs(canvas, mBigOval, mUseCenters[mBigIndex],
mPaints[mBigIndex]);
-
+
for (int i = 0; i < 4; i++) {
drawArcs(canvas, mOvals[i], mUseCenters[i], mPaints[i]);
}
-
+
mSweep += SWEEP_INC;
if (mSweep > 360) {
mSweep -= 360;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
index 88f0c1d..6a8b542 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.java
@@ -18,36 +18,36 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
-import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
public class BitmapDecode extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Bitmap mBitmap;
private Bitmap mBitmap2;
private Bitmap mBitmap3;
private Bitmap mBitmap4;
private Drawable mDrawable;
-
+
private Movie mMovie;
private long mMovieStart;
-
+
+ //Set to false to use decodeByteArray
+ private static final boolean DECODE_STREAM = true;
+
private static byte[] streamToBytes(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
@@ -60,33 +60,33 @@
}
return os.toByteArray();
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
java.io.InputStream is;
is = context.getResources().openRawResource(R.drawable.beach);
-
+
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm;
-
+
opts.inJustDecodeBounds = true;
bm = BitmapFactory.decodeStream(is, null, opts);
-
+
// now opts.outWidth and opts.outHeight are the dimension of the
// bitmap, even though bm is null
-
+
opts.inJustDecodeBounds = false; // this will request the bm
opts.inSampleSize = 4; // scaled down by 4
bm = BitmapFactory.decodeStream(is, null, opts);
-
+
mBitmap = bm;
-
+
// decode an image with transparency
is = context.getResources().openRawResource(R.drawable.frog);
mBitmap2 = BitmapFactory.decodeStream(is);
-
+
// create a deep copy of it using getPixels() into different configs
int w = mBitmap2.getWidth();
int h = mBitmap2.getHeight();
@@ -96,32 +96,34 @@
Bitmap.Config.ARGB_8888);
mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
Bitmap.Config.ARGB_4444);
-
+
mDrawable = context.getResources().getDrawable(R.drawable.button);
mDrawable.setBounds(150, 20, 300, 100);
-
+
is = context.getResources().openRawResource(R.drawable.animated_gif);
- if (true) {
+
+ if (DECODE_STREAM) {
mMovie = Movie.decodeStream(is);
} else {
byte[] array = streamToBytes(is);
mMovie = Movie.decodeByteArray(array, 0, array.length);
}
}
-
- @Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFCCCCCC);
-
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawColor(0xFFCCCCCC);
+
Paint p = new Paint();
p.setAntiAlias(true);
-
+
canvas.drawBitmap(mBitmap, 10, 10, null);
canvas.drawBitmap(mBitmap2, 10, 170, null);
canvas.drawBitmap(mBitmap3, 110, 170, null);
canvas.drawBitmap(mBitmap4, 210, 170, null);
-
+
mDrawable.draw(canvas);
-
+
long now = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) { // first time
mMovieStart = now;
@@ -140,4 +142,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
index 4d48a1e..12c79ca 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapMesh.java
@@ -31,16 +31,16 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private static final int WIDTH = 20;
private static final int HEIGHT = 20;
private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
-
+
private final Bitmap mBitmap;
private final float[] mVerts = new float[COUNT*2];
private final float[] mOrig = new float[COUNT*2];
-
+
private final Matrix mMatrix = new Matrix();
private final Matrix mInverse = new Matrix();
@@ -55,7 +55,7 @@
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.beach);
-
+
float w = mBitmap.getWidth();
float h = mBitmap.getHeight();
// construct our mesh
@@ -63,17 +63,17 @@
for (int y = 0; y <= HEIGHT; y++) {
float fy = h * y / HEIGHT;
for (int x = 0; x <= WIDTH; x++) {
- float fx = w * x / WIDTH;
+ float fx = w * x / WIDTH;
setXY(mVerts, index, fx, fy);
setXY(mOrig, index, fx, fy);
index += 1;
}
}
-
+
mMatrix.setTranslate(10, 10);
mMatrix.invert(mInverse);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);
@@ -81,7 +81,7 @@
canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0,
null, 0, null);
}
-
+
private void warp(float cx, float cy) {
final float K = 10000;
float[] src = mOrig;
@@ -94,7 +94,7 @@
float dd = dx*dx + dy*dy;
float d = FloatMath.sqrt(dd);
float pull = K / (dd + 0.000001f);
-
+
pull /= (d + 0.000001f);
// android.util.Log.d("skia", "index " + i + " dist=" + d + " pull=" + pull);
@@ -114,7 +114,7 @@
@Override public boolean onTouchEvent(MotionEvent event) {
float[] pt = { event.getX(), event.getY() };
mInverse.mapPoints(pt);
-
+
int x = (int)pt[0];
int y = (int)pt[1];
if (mLastWarpX != x || mLastWarpY != y) {
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
index 88717bc..e9b2167 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapPixels.java
@@ -16,32 +16,26 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
-import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
public class BitmapPixels extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Bitmap mBitmap1;
private Bitmap mBitmap2;
private Bitmap mBitmap3;
- private Bitmap mBitmap4;
// access the red component from a premultiplied color
private static int getR32(int c) { return (c >> 0) & 0xFF; }
@@ -67,7 +61,7 @@
private static short pack4444(int r, int g, int b, int a) {
return (short)((a << 0) | ( b << 4) | (g << 8) | (r << 12));
}
-
+
private static int mul255(int c, int a) {
int prod = c * a + 128;
return (prod + (prod >> 8)) >> 8;
@@ -88,7 +82,7 @@
// now pack it in the correct order
return pack8888(r, g, b, a);
}
-
+
private static void makeRamp(int from, int to, int n,
int[] ramp8888, short[] ramp565,
short[] ramp4444) {
@@ -113,7 +107,7 @@
a += da;
}
}
-
+
private static IntBuffer makeBuffer(int[] src, int n) {
IntBuffer dst = IntBuffer.allocate(n*n);
for (int i = 0; i < n; i++) {
@@ -122,7 +116,7 @@
dst.rewind();
return dst;
}
-
+
private static ShortBuffer makeBuffer(short[] src, int n) {
ShortBuffer dst = ShortBuffer.allocate(n*n);
for (int i = 0; i < n; i++) {
@@ -131,31 +125,31 @@
dst.rewind();
return dst;
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
final int N = 100;
int[] data8888 = new int[N];
short[] data565 = new short[N];
short[] data4444 = new short[N];
-
+
makeRamp(premultiplyColor(Color.RED), premultiplyColor(Color.GREEN),
N, data8888, data565, data4444);
-
+
mBitmap1 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_8888);
mBitmap2 = Bitmap.createBitmap(N, N, Bitmap.Config.RGB_565);
mBitmap3 = Bitmap.createBitmap(N, N, Bitmap.Config.ARGB_4444);
-
+
mBitmap1.copyPixelsFromBuffer(makeBuffer(data8888, N));
mBitmap2.copyPixelsFromBuffer(makeBuffer(data565, N));
mBitmap3.copyPixelsFromBuffer(makeBuffer(data4444, N));
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFCCCCCC);
-
+ canvas.drawColor(0xFFCCCCCC);
+
int y = 10;
canvas.drawBitmap(mBitmap1, 10, y, null);
y += mBitmap1.getHeight() + 10;
@@ -165,4 +159,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
index cf83597..42f8be3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Clipping.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private Path mPath;
@@ -37,46 +36,46 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(6);
mPaint.setTextSize(16);
mPaint.setTextAlign(Paint.Align.RIGHT);
-
+
mPath = new Path();
}
-
+
private void drawScene(Canvas canvas) {
canvas.clipRect(0, 0, 100, 100);
-
+
canvas.drawColor(Color.WHITE);
-
+
mPaint.setColor(Color.RED);
canvas.drawLine(0, 0, 100, 100, mPaint);
-
+
mPaint.setColor(Color.GREEN);
canvas.drawCircle(30, 70, 30, mPaint);
-
+
mPaint.setColor(Color.BLUE);
canvas.drawText("Clipping", 100, 30, mPaint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.GRAY);
+ canvas.drawColor(Color.GRAY);
canvas.save();
canvas.translate(10, 10);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 10);
canvas.clipRect(10, 10, 90, 90);
canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10, 160);
mPath.reset();
@@ -85,21 +84,21 @@
canvas.clipPath(mPath, Region.Op.REPLACE);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 160);
canvas.clipRect(0, 0, 60, 60);
canvas.clipRect(40, 40, 100, 100, Region.Op.UNION);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10, 310);
canvas.clipRect(0, 0, 60, 60);
canvas.clipRect(40, 40, 100, 100, Region.Op.XOR);
drawScene(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 310);
canvas.clipRect(0, 0, 60, 60);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java
index 92d18ba..8eb60b5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorFilters.java
@@ -23,18 +23,17 @@
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class ColorFilters extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
-
+
}
-
+
private static class SampleView extends View {
private Activity mActivity;
private Drawable mDrawable;
@@ -52,7 +51,7 @@
int center = (r.top + r.bottom) >> 1;
int h = curr.getIntrinsicHeight();
int y = center - (h >> 1);
-
+
curr.setBounds(x, y, x + curr.getIntrinsicWidth(), y + h);
}
@@ -61,7 +60,7 @@
mActivity = activity;
Context context = activity;
setFocusable(true);
-
+
mDrawable = context.getResources().getDrawable(R.drawable.btn_default_normal);
mDrawable.setBounds(0, 0, 150, 48);
mDrawable.setDither(true);
@@ -84,13 +83,13 @@
mPaint.setAntiAlias(true);
mPaint.setTextSize(16);
mPaint.setTextAlign(Paint.Align.CENTER);
-
+
mPaint2 = new Paint(mPaint);
mPaint2.setAlpha(64);
-
+
Paint.FontMetrics fm = mPaint.getFontMetrics();
mPaintTextOffset = (fm.descent + fm.ascent) * 0.5f;
-
+
mColors = new int[] {
0,
0xCC0000FF,
@@ -106,10 +105,10 @@
PorterDuff.Mode.MULTIPLY,
};
mModeIndex = 0;
-
+
updateTitle();
}
-
+
private void swapPaintColors() {
if (mPaint.getColor() == 0xFF000000) {
mPaint.setColor(0xFFFFFFFF);
@@ -120,11 +119,11 @@
}
mPaint2.setAlpha(64);
}
-
+
private void updateTitle() {
mActivity.setTitle(mModes[mModeIndex].toString());
}
-
+
private void drawSample(Canvas canvas, ColorFilter filter) {
Rect r = mDrawable.getBounds();
float x = (r.left + r.right) * 0.5f;
@@ -134,15 +133,15 @@
mDrawable.draw(canvas);
canvas.drawText("Label", x+1, y+1, mPaint2);
canvas.drawText("Label", x, y, mPaint);
-
+
for (Drawable dr : mDrawables) {
dr.setColorFilter(filter);
dr.draw(canvas);
}
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFCCCCCC);
+ canvas.drawColor(0xFFCCCCCC);
canvas.translate(8, 12);
for (int color : mColors) {
@@ -160,8 +159,6 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
@@ -181,4 +178,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
index 19a0f7f..f438e73 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorMatrixSample.java
@@ -18,35 +18,31 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
public class ColorMatrixSample extends GraphicsActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private ColorMatrix mCM = new ColorMatrix();
private Bitmap mBitmap;
- private float mSaturation;
private float mAngle;
-
+
public SampleView(Context context) {
super(context);
-
+
mBitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.balloons);
}
-
+
private static void setTranslate(ColorMatrix cm, float dr, float dg,
float db, float da) {
cm.set(new float[] {
@@ -55,7 +51,7 @@
0, 0, 2, 0, db,
0, 0, 0, 1, da });
}
-
+
private static void setContrast(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
@@ -65,7 +61,7 @@
0, 0, scale, 0, translate,
0, 0, 0, 1, 0 });
}
-
+
private static void setContrastTranslateOnly(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
@@ -75,7 +71,7 @@
0, 0, 1, 0, translate,
0, 0, 0, 1, 0 });
}
-
+
private static void setContrastScaleOnly(ColorMatrix cm, float contrast) {
float scale = contrast + 1.f;
float translate = (-.5f * scale + .5f) * 255.f;
@@ -85,40 +81,40 @@
0, 0, scale, 0, 0,
0, 0, 0, 1, 0 });
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
float x = 20;
float y = 20;
-
+
canvas.drawColor(Color.WHITE);
-
+
paint.setColorFilter(null);
canvas.drawBitmap(mBitmap, x, y, paint);
-
+
ColorMatrix cm = new ColorMatrix();
-
+
mAngle += 2;
if (mAngle > 180) {
mAngle = 0;
}
-
+
//convert our animated angle [-180...180] to a contrast value of [-1..1]
float contrast = mAngle / 180.f;
-
+
setContrast(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x + mBitmap.getWidth() + 10, y, paint);
-
+
setContrastScaleOnly(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x, y + mBitmap.getHeight() + 10, paint);
-
+
setContrastTranslateOnly(cm, contrast);
paint.setColorFilter(new ColorMatrixColorFilter(cm));
canvas.drawBitmap(mBitmap, x, y + 2*(mBitmap.getHeight() + 10),
paint);
-
+
invalidate();
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
index 7588180..1c7125f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ColorPickerDialog.java
@@ -37,7 +37,7 @@
private Paint mCenterPaint;
private final int[] mColors;
private OnColorChangedListener mListener;
-
+
ColorPickerView(Context c, OnColorChangedListener l, int color) {
super(c);
mListener = l;
@@ -46,33 +46,33 @@
0xFFFFFF00, 0xFFFF0000
};
Shader s = new SweepGradient(0, 0, mColors, null);
-
+
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(32);
-
+
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(color);
mCenterPaint.setStrokeWidth(5);
}
-
+
private boolean mTrackingCenter;
private boolean mHighlightCenter;
- @Override
+ @Override
protected void onDraw(Canvas canvas) {
float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;
-
+
canvas.translate(CENTER_X, CENTER_X);
-
- canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
+
+ canvas.drawOval(new RectF(-r, -r, r, r), mPaint);
canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
-
+
if (mTrackingCenter) {
int c = mCenterPaint.getColor();
mCenterPaint.setStyle(Paint.Style.STROKE);
-
+
if (mHighlightCenter) {
mCenterPaint.setAlpha(0xFF);
} else {
@@ -81,17 +81,17 @@
canvas.drawCircle(0, 0,
CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
mCenterPaint);
-
+
mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}
}
-
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
}
-
+
private static final int CENTER_X = 100;
private static final int CENTER_Y = 100;
private static final int CENTER_RADIUS = 32;
@@ -108,11 +108,11 @@
}
return n;
}
-
+
private int ave(int s, int d, float p) {
return s + java.lang.Math.round(p * (d - s));
}
-
+
private int interpColor(int colors[], float unit) {
if (unit <= 0) {
return colors[0];
@@ -120,7 +120,7 @@
if (unit >= 1) {
return colors[colors.length - 1];
}
-
+
float p = unit * (colors.length - 1);
int i = (int)p;
p -= i;
@@ -132,16 +132,16 @@
int r = ave(Color.red(c0), Color.red(c1), p);
int g = ave(Color.green(c0), Color.green(c1), p);
int b = ave(Color.blue(c0), Color.blue(c1), p);
-
+
return Color.argb(a, r, g, b);
}
-
+
private int rotateColor(int color, float rad) {
float deg = rad * 180 / 3.1415927f;
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
-
+
ColorMatrix cm = new ColorMatrix();
ColorMatrix tmp = new ColorMatrix();
@@ -150,17 +150,17 @@
cm.postConcat(tmp);
tmp.setYUV2RGB();
cm.postConcat(tmp);
-
+
final float[] a = cm.getArray();
int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);
int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);
int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);
-
+
return Color.argb(Color.alpha(color), pinToByte(ir),
pinToByte(ig), pinToByte(ib));
}
-
+
private static final float PI = 3.1415926f;
@Override
@@ -168,7 +168,7 @@
float x = event.getX() - CENTER_X;
float y = event.getY() - CENTER_Y;
boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;
-
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTrackingCenter = inCenter;
@@ -212,7 +212,7 @@
OnColorChangedListener listener,
int initialColor) {
super(context);
-
+
mListener = listener;
mInitialColor = initialColor;
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
index d3b0981..85471d9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Compass.java
@@ -35,10 +35,10 @@
private Sensor mSensor;
private SampleView mView;
private float[] mValues;
-
+
private final SensorEventListener mListener = new SensorEventListener() {
public void onSensorChanged(SensorEvent event) {
- if (Config.LOGD) Log.d(TAG,
+ if (Config.DEBUG) Log.d(TAG,
"sensorChanged (" + event.values[0] + ", " + event.values[1] + ", " + event.values[2] + ")");
mValues = event.values;
if (mView != null) {
@@ -62,17 +62,17 @@
@Override
protected void onResume()
{
- if (Config.LOGD) Log.d(TAG, "onResume");
+ if (Config.DEBUG) Log.d(TAG, "onResume");
super.onResume();
mSensorManager.registerListener(mListener, mSensor,
SensorManager.SENSOR_DELAY_GAME);
}
-
+
@Override
protected void onStop()
{
- if (Config.LOGD) Log.d(TAG, "onStop");
+ if (Config.DEBUG) Log.d(TAG, "onStop");
mSensorManager.unregisterListener(mListener);
super.onStop();
}
@@ -81,7 +81,6 @@
private Paint mPaint = new Paint();
private Path mPath = new Path();
private boolean mAnimate;
- private long mNextTime;
public SampleView(Context context) {
super(context);
@@ -93,12 +92,12 @@
mPath.lineTo(20, 60);
mPath.close();
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(Color.WHITE);
-
+
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
@@ -109,23 +108,24 @@
int cy = h / 2;
canvas.translate(cx, cy);
- if (mValues != null) {
+ if (mValues != null) {
canvas.rotate(-mValues[0]);
}
canvas.drawPath(mPath, mPaint);
}
-
+
@Override
protected void onAttachedToWindow() {
mAnimate = true;
+ if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate=" + mAnimate);
super.onAttachedToWindow();
}
-
+
@Override
protected void onDetachedFromWindow() {
mAnimate = false;
+ if (Config.DEBUG) Log.d(TAG, "onDetachedFromWindow. mAnimate=" + mAnimate);
super.onDetachedFromWindow();
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
index e3e5d9a..61fe9d5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CreateBitmap.java
@@ -16,13 +16,9 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
import java.io.ByteArrayOutputStream;
@@ -34,11 +30,11 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static final int WIDTH = 50;
private static final int HEIGHT = 50;
private static final int STRIDE = 64; // must be >= WIDTH
-
+
private static int[] createColors() {
int[] colors = new int[STRIDE * HEIGHT];
for (int y = 0; y < HEIGHT; y++) {
@@ -52,18 +48,18 @@
}
return colors;
}
-
+
private static class SampleView extends View {
private Bitmap[] mBitmaps;
private Bitmap[] mJPEG;
private Bitmap[] mPNG;
private int[] mColors;
private Paint mPaint;
-
+
private static Bitmap codec(Bitmap src, Bitmap.CompressFormat format,
int quality) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
- src.compress(format, quality, os);
+ src.compress(format, quality, os);
byte[] array = os.toByteArray();
return BitmapFactory.decodeByteArray(array, 0, array.length);
@@ -72,7 +68,7 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mColors = createColors();
int[] colors = mColors;
@@ -84,7 +80,7 @@
Bitmap.Config.RGB_565);
mBitmaps[2] = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
Bitmap.Config.ARGB_4444);
-
+
// these three will have their colors set later
mBitmaps[3] = Bitmap.createBitmap(WIDTH, HEIGHT,
Bitmap.Config.ARGB_8888);
@@ -95,10 +91,10 @@
for (int i = 3; i <= 5; i++) {
mBitmaps[i].setPixels(colors, 0, STRIDE, 0, 0, WIDTH, HEIGHT);
}
-
+
mPaint = new Paint();
mPaint.setDither(true);
-
+
// now encode/decode using JPEG and PNG
mJPEG = new Bitmap[mBitmaps.length];
mPNG = new Bitmap[mBitmaps.length];
@@ -107,7 +103,7 @@
mPNG[i] = codec(mBitmaps[i], Bitmap.CompressFormat.PNG, 0);
}
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
@@ -117,7 +113,7 @@
canvas.drawBitmap(mPNG[i], 160, 0, null);
canvas.translate(0, mBitmaps[i].getHeight());
}
-
+
// draw the color array directly, w/o craeting a bitmap object
canvas.drawBitmap(mColors, 0, STRIDE, 0, 0, WIDTH, HEIGHT,
true, null);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
index bb154eb..715e175 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Cube.java
@@ -88,10 +88,10 @@
public void draw(GL10 gl)
{
- gl.glFrontFace(gl.GL_CW);
- gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
- gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
- gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
+ gl.glFrontFace(GL10.GL_CW);
+ gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
+ gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
+ gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
}
private IntBuffer mVertexBuffer;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
index 0f15f91..ac0ae27 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeRenderer.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java
index 8c5c93a..0288ad1 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.java
@@ -47,7 +47,7 @@
final LayoutInflater li = (LayoutInflater)getSystemService(
LAYOUT_INFLATER_SERVICE);
-
+
this.setTitle(R.string.density_title);
LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
@@ -76,11 +76,11 @@
layout = (LinearLayout)li.inflate(R.layout.density_image_views, null);
addLabelToRoot(root, "Inflated layout");
addChildToRoot(root, layout);
-
+
layout = (LinearLayout)li.inflate(R.layout.density_styled_image_views, null);
addLabelToRoot(root, "Inflated styled layout");
addChildToRoot(root, layout);
-
+
layout = new LinearLayout(this);
addCanvasBitmap(layout, R.drawable.logo120dpi, true);
addCanvasBitmap(layout, R.drawable.logo160dpi, true);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java b/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
index cbe6373..21eba0d 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint();
private float[] mPts;
@@ -38,11 +37,11 @@
private static final int SEGS = 32;
private static final int X = 0;
private static final int Y = 1;
-
+
private void buildPoints() {
final int ptCount = (SEGS + 1) * 2;
mPts = new float[ptCount * 2];
-
+
float value = 0;
final float delta = SIZE / SEGS;
for (int i = 0; i <= SEGS; i++) {
@@ -53,16 +52,16 @@
value += delta;
}
}
-
+
public SampleView(Context context) {
super(context);
-
+
buildPoints();
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
-
+
canvas.translate(10, 10);
canvas.drawColor(Color.WHITE);
@@ -70,7 +69,7 @@
paint.setColor(Color.RED);
paint.setStrokeWidth(0);
canvas.drawLines(mPts, paint);
-
+
paint.setColor(Color.BLUE);
paint.setStrokeWidth(3);
canvas.drawPoints(mPts, paint);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
index 867da4c..fcfd28f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/FingerPaint.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -26,7 +25,7 @@
import android.view.View;
public class FingerPaint extends GraphicsActivity
- implements ColorPickerDialog.OnColorChangedListener {
+ implements ColorPickerDialog.OnColorChangedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -41,34 +40,34 @@
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
-
+
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
0.4f, 6, 3.5f);
mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
}
-
+
private Paint mPaint;
private MaskFilter mEmboss;
private MaskFilter mBlur;
-
+
public void colorChanged(int color) {
mPaint.setColor(color);
}
public class MyView extends View {
-
+
private static final float MINP = 0.25f;
private static final float MAXP = 0.75f;
-
+
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
-
+
public MyView(Context c) {
super(c);
-
+
mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
@@ -79,19 +78,19 @@
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
-
+
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
-
+
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
-
+
canvas.drawPath(mPath, mPaint);
}
-
+
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
-
+
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
@@ -114,12 +113,12 @@
// kill this so we don't double draw
mPath.reset();
}
-
+
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
-
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
@@ -137,7 +136,7 @@
return true;
}
}
-
+
private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
private static final int BLUR_MENU_ID = Menu.FIRST + 2;
@@ -147,7 +146,7 @@
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
-
+
menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
@@ -164,13 +163,13 @@
*****/
return true;
}
-
+
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
-
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
mPaint.setXfermode(null);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java b/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
index eb6d47d..fa7a6b7 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/GradientDrawable1.java
@@ -20,7 +20,6 @@
// class is in a sub-package.
import com.example.android.apis.R;
-import android.app.Activity;
import android.os.Bundle;
public class GradientDrawable1 extends GraphicsActivity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
index 023c0d7..69682d4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/GraphicsActivity.java
@@ -20,9 +20,11 @@
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
-import android.view.Window;
class GraphicsActivity extends Activity {
+ // set to true to test Picture
+ private static final boolean TEST_PICTURE = false;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -30,13 +32,12 @@
@Override
public void setContentView(View view) {
- if (false) { // set to true to test Picture
+ if (TEST_PICTURE) {
ViewGroup vg = new PictureLayout(this);
vg.addView(view);
view = vg;
}
-
+
super.setContentView(view);
}
-}
-
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
index d9f5db0..7e2a694 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Layers.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private static final int LAYER_FLAGS = Canvas.MATRIX_SAVE_FLAG |
Canvas.CLIP_SAVE_FLAG |
@@ -42,23 +41,23 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.WHITE);
-
+ canvas.drawColor(Color.WHITE);
+
canvas.translate(10, 10);
-
+
canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS);
-
+
mPaint.setColor(Color.RED);
canvas.drawCircle(75, 75, 75, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawCircle(125, 125, 75, mPaint);
-
+
canvas.restore();
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java b/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
index e159efe..c2d433e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/MeasureText.java
@@ -16,13 +16,9 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class MeasureText extends GraphicsActivity {
@@ -32,11 +28,11 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static final int WIDTH = 50;
private static final int HEIGHT = 50;
private static final int STRIDE = 64; // must be >= WIDTH
-
+
private static int[] createColors() {
int[] colors = new int[STRIDE * HEIGHT];
for (int y = 0; y < HEIGHT; y++) {
@@ -50,16 +46,16 @@
}
return colors;
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private float mOriginX = 10;
private float mOriginY = 80;
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(5);
@@ -68,22 +64,22 @@
mPaint.setTypeface(Typeface.create(Typeface.SERIF,
Typeface.ITALIC));
}
-
+
private void showText(Canvas canvas, String text, Paint.Align align) {
// mPaint.setTextAlign(align);
-
+
Rect bounds = new Rect();
float[] widths = new float[text.length()];
int count = mPaint.getTextWidths(text, 0, text.length(), widths);
float w = mPaint.measureText(text, 0, text.length());
mPaint.getTextBounds(text, 0, text.length(), bounds);
-
+
mPaint.setColor(0xFF88FF88);
canvas.drawRect(bounds, mPaint);
mPaint.setColor(Color.BLACK);
canvas.drawText(text, 0, 0, mPaint);
-
+
float[] pts = new float[2 + count*2];
float x = 0;
float y = 0;
@@ -100,12 +96,12 @@
mPaint.setStrokeWidth(5);
canvas.drawPoints(pts, 0, (count + 1) << 1, mPaint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
canvas.translate(mOriginX, mOriginY);
-
+
showText(canvas, "Measure", Paint.Align.LEFT);
canvas.translate(0, 80);
showText(canvas, "wiggy!", Paint.Align.CENTER);
@@ -114,4 +110,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
index 80ddf38..2894fa9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -30,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private Path mPath;
@@ -41,7 +40,7 @@
private static PathEffect makeDash(float phase) {
return new DashPathEffect(new float[] { 15, 5, 8, 5 }, phase);
}
-
+
private static void makeEffects(PathEffect[] e, float phase) {
e[0] = null; // no effect
e[1] = new CornerPathEffect(10);
@@ -51,7 +50,7 @@
e[4] = new ComposePathEffect(e[2], e[1]);
e[5] = new ComposePathEffect(e[3], e[1]);
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
@@ -60,23 +59,23 @@
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(6);
-
+
mPath = makeFollowPath();
-
+
mEffects = new PathEffect[6];
-
+
mColors = new int[] { Color.BLACK, Color.RED, Color.BLUE,
Color.GREEN, Color.MAGENTA, Color.BLACK
};
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
RectF bounds = new RectF();
mPath.computeBounds(bounds, false);
canvas.translate(10 - bounds.left, 10 - bounds.top);
-
+
makeEffects(mEffects, mPhase);
mPhase += 1;
invalidate();
@@ -88,7 +87,7 @@
canvas.translate(0, 28);
}
}
-
+
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
@@ -106,7 +105,7 @@
}
return p;
}
-
+
private static Path makePathDash() {
Path p = new Path();
p.moveTo(4, 0);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
index 78dba26..10cfc49 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PathFillTypes.java
@@ -20,11 +20,9 @@
// class is in a sub-package.
//import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
public class PathFillTypes extends GraphicsActivity {
@@ -34,7 +32,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mPath;
@@ -48,7 +46,7 @@
mPath.addCircle(40, 40, 45, Path.Direction.CCW);
mPath.addCircle(80, 80, 45, Path.Direction.CCW);
}
-
+
private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
Paint paint) {
canvas.save();
@@ -59,14 +57,14 @@
canvas.drawPath(mPath, paint);
canvas.restore();
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(0xFFCCCCCC);
-
+
canvas.translate(20, 20);
-
+
paint.setAntiAlias(true);
showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
index d2a51ff..6b6d8e1 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Patterns.java
@@ -16,11 +16,9 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.*;
@@ -31,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static Bitmap makeBitmap1() {
Bitmap bm = Bitmap.createBitmap(40, 40, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bm);
@@ -41,7 +39,7 @@
c.drawRect(5, 5, 35, 35, p);
return bm;
}
-
+
private static Bitmap makeBitmap2() {
Bitmap bm = Bitmap.createBitmap(64, 64, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
@@ -51,13 +49,13 @@
c.drawCircle(32, 32, 27, p);
return bm;
}
-
+
private static class SampleView extends View {
private final Shader mShader1;
private final Shader mShader2;
private final Paint mPaint;
private final DrawFilter mFastDF;
-
+
private float mTouchStartX;
private float mTouchStartY;
private float mTouchCurrX;
@@ -72,25 +70,25 @@
mFastDF = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG |
Paint.DITHER_FLAG,
0);
-
+
mShader1 = new BitmapShader(makeBitmap1(), Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
mShader2 = new BitmapShader(makeBitmap2(), Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
-
+
Matrix m = new Matrix();
m.setRotate(30);
mShader2.setLocalMatrix(m);
-
+
mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.setDrawFilter(mDF);
mPaint.setShader(mShader1);
canvas.drawPaint(mPaint);
-
+
canvas.translate(mTouchCurrX - mTouchStartX,
mTouchCurrY - mTouchStartY);
@@ -102,7 +100,7 @@
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
-
+
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTouchStartX = mTouchCurrX = x;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
index cfa3c29..c1d22a8 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PictureLayout.java
@@ -26,7 +26,6 @@
import android.view.ViewGroup;
import android.view.ViewParent;
-
public class PictureLayout extends ViewGroup {
private final Picture mPicture = new Picture();
@@ -36,7 +35,7 @@
public PictureLayout(Context context, AttributeSet attrs) {
super(context, attrs);
- }
+ }
@Override
public void addView(View child) {
@@ -105,7 +104,7 @@
setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
resolveSize(maxHeight, heightMeasureSpec));
}
-
+
private void drawPict(Canvas canvas, int x, int y, int w, int h,
float sx, float sy) {
canvas.save();
@@ -121,10 +120,10 @@
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
mPicture.endRecording();
-
+
int x = getWidth()/2;
int y = getHeight()/2;
-
+
if (false) {
canvas.drawPicture(mPicture);
} else {
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
index 1bd0a8c..61842dd 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Pictures.java
@@ -16,13 +16,11 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.View;
import java.io.*;
@@ -34,17 +32,17 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Picture mPicture;
private Drawable mDrawable;
static void drawSomething(Canvas canvas) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
+
p.setColor(0x88FF0000);
canvas.drawCircle(50, 50, 40, p);
-
+
p.setColor(Color.GREEN);
p.setTextSize(30);
canvas.drawText("Pictures", 60, 60, p);
@@ -58,20 +56,20 @@
mPicture = new Picture();
drawSomething(mPicture.beginRecording(200, 100));
mPicture.endRecording();
-
+
mDrawable = new PictureDrawable(mPicture);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.drawPicture(mPicture);
-
+
canvas.drawPicture(mPicture, new RectF(0, 100, getWidth(), 200));
-
+
mDrawable.setBounds(0, 200, getWidth(), 300);
mDrawable.draw(canvas);
-
+
ByteArrayOutputStream os = new ByteArrayOutputStream();
mPicture.writeToStream(os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java b/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
index 15d92de..a1f1ed4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/PolyToPoly.java
@@ -20,7 +20,6 @@
// class is in a sub-package.
//import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -33,7 +32,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Matrix mMatrix = new Matrix();
@@ -43,13 +42,13 @@
canvas.save();
mMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
canvas.concat(mMatrix);
-
+
mPaint.setColor(Color.GRAY);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawRect(0, 0, 64, 64, mPaint);
canvas.drawLine(0, 0, 64, 64, mPaint);
canvas.drawLine(0, 64, 64, 0, mPaint);
-
+
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
// how to draw the text center on our square
@@ -58,7 +57,7 @@
// centering in Y, we need to measure ascent/descent first
float y = 64/2 - (mFontMetrics.ascent + mFontMetrics.descent)/2;
canvas.drawText(src.length/2 + "", x, y, mPaint);
-
+
canvas.restore();
}
@@ -72,10 +71,9 @@
mPaint.setTextAlign(Paint.Align.CENTER);
mFontMetrics = mPaint.getFontMetrics();
}
-
- @Override protected void onDraw(Canvas canvas) {
- Paint paint = mPaint;
+ @Override
+ protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.save();
@@ -83,7 +81,7 @@
// translate (1 point)
doDraw(canvas, new float[] { 0, 0 }, new float[] { 5, 5 });
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 10);
// rotate/uniform-scale (2 points)
@@ -107,4 +105,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
index d264134..635132e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ProxyDrawable.java
@@ -22,18 +22,18 @@
import android.graphics.drawable.Drawable;
public class ProxyDrawable extends Drawable {
-
+
private Drawable mProxy;
private boolean mMutated;
public ProxyDrawable(Drawable target) {
mProxy = target;
}
-
+
public Drawable getProxy() {
return mProxy;
}
-
+
public void setProxy(Drawable proxy) {
if (proxy != this) {
mProxy = proxy;
@@ -46,43 +46,43 @@
mProxy.draw(canvas);
}
}
-
+
@Override
public int getIntrinsicWidth() {
return mProxy != null ? mProxy.getIntrinsicWidth() : -1;
}
-
+
@Override
public int getIntrinsicHeight() {
return mProxy != null ? mProxy.getIntrinsicHeight() : -1;
}
-
+
@Override
public int getOpacity() {
return mProxy != null ? mProxy.getOpacity() : PixelFormat.TRANSPARENT;
}
-
+
@Override
public void setFilterBitmap(boolean filter) {
if (mProxy != null) {
mProxy.setFilterBitmap(filter);
}
}
-
+
@Override
public void setDither(boolean dither) {
if (mProxy != null) {
mProxy.setDither(dither);
}
}
-
+
@Override
public void setColorFilter(ColorFilter colorFilter) {
if (mProxy != null) {
mProxy.setColorFilter(colorFilter);
}
}
-
+
@Override
public void setAlpha(int alpha) {
if (mProxy != null) {
@@ -99,4 +99,4 @@
return this;
}
}
-
+
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
index 833274b..fc0aa08 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Regions.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,7 +28,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private final Paint mPaint = new Paint();
private final Rect mRect1 = new Rect();
@@ -38,11 +37,11 @@
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint.setAntiAlias(true);
mPaint.setTextSize(16);
mPaint.setTextAlign(Paint.Align.CENTER);
-
+
mRect1.set(10, 10, 100, 80);
mRect2.set(50, 50, 130, 110);
}
@@ -55,25 +54,25 @@
mPaint.setColor(Color.BLUE);
mPaint.setAlpha(alpha);
drawCentered(canvas, mRect2, mPaint);
-
+
// restore style
mPaint.setStyle(Paint.Style.FILL);
}
-
+
private void drawRgn(Canvas canvas, int color, String str, Region.Op op) {
if (str != null) {
mPaint.setColor(Color.BLACK);
canvas.drawText(str, 80, 24, mPaint);
}
-
+
Region rgn = new Region();
rgn.set(mRect1);
rgn.op(mRect2, op);
-
+
mPaint.setColor(color);
RegionIterator iter = new RegionIterator(rgn);
Rect r = new Rect();
-
+
canvas.translate(0, 30);
mPaint.setColor(color);
while (iter.next(r)) {
@@ -81,7 +80,7 @@
}
drawOriginalRects(canvas, 0x80);
}
-
+
private static void drawCentered(Canvas c, Rect r, Paint p) {
float inset = p.getStrokeWidth() * 0.5f;
if (inset == 0) { // catch hairlines
@@ -90,32 +89,33 @@
c.drawRect(r.left + inset, r.top + inset,
r.right - inset, r.bottom - inset, p);
}
-
- @Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.GRAY);
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawColor(Color.GRAY);
canvas.save();
canvas.translate(80, 5);
drawOriginalRects(canvas, 0xFF);
canvas.restore();
-
+
mPaint.setStyle(Paint.Style.FILL);
-
+
canvas.save();
canvas.translate(0, 140);
drawRgn(canvas, Color.RED, "Union", Region.Op.UNION);
canvas.restore();
-
+
canvas.save();
canvas.translate(0, 280);
drawRgn(canvas, Color.BLUE, "Xor", Region.Op.XOR);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 140);
drawRgn(canvas, Color.GREEN, "Difference", Region.Op.DIFFERENCE);
canvas.restore();
-
+
canvas.save();
canvas.translate(160, 280);
drawRgn(canvas, Color.WHITE, "Intersect", Region.Op.INTERSECT);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java b/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
index b0ff0359..74c2406 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/RoundRects.java
@@ -16,14 +16,10 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class RoundRects extends GraphicsActivity {
@@ -33,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Path mPath;
private Paint mPaint;
@@ -47,73 +43,71 @@
mPath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRect = new Rect(0, 0, 120, 120);
-
+
mDrawable = new GradientDrawable(GradientDrawable.Orientation.TL_BR,
new int[] { 0xFFFF0000, 0xFF00FF00,
0xFF0000FF });
mDrawable.setShape(GradientDrawable.RECTANGLE);
mDrawable.setGradientRadius((float)(Math.sqrt(2) * 60));
}
-
+
static void setCornerRadii(GradientDrawable drawable, float r0,
float r1, float r2, float r3) {
drawable.setCornerRadii(new float[] { r0, r0, r1, r1,
r2, r2, r3, r3 });
}
-
+
@Override protected void onDraw(Canvas canvas) {
-
+
mDrawable.setBounds(mRect);
float r = 16;
-
+
canvas.save();
canvas.translate(10, 10);
mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
setCornerRadii(mDrawable, r, r, 0, 0);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10 + mRect.width() + 10, 10);
mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
setCornerRadii(mDrawable, 0, 0, r, r);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.translate(0, mRect.height() + 10);
-
+
canvas.save();
canvas.translate(10, 10);
mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
setCornerRadii(mDrawable, 0, r, r, 0);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10 + mRect.width() + 10, 10);
mDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
setCornerRadii(mDrawable, r, 0, 0, r);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.translate(0, mRect.height() + 10);
-
+
canvas.save();
canvas.translate(10, 10);
mDrawable.setGradientType(GradientDrawable.RADIAL_GRADIENT);
setCornerRadii(mDrawable, r, 0, r, 0);
mDrawable.draw(canvas);
canvas.restore();
-
+
canvas.save();
canvas.translate(10 + mRect.width() + 10, 10);
mDrawable.setGradientType(GradientDrawable.SWEEP_GRADIENT);
setCornerRadii(mDrawable, 0, r, 0, r);
mDrawable.draw(canvas);
canvas.restore();
-
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
index f55e55b..6ffdb5b 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ScaleToFit.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,14 +28,14 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mHairPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Matrix mMatrix = new Matrix();
private final RectF mSrcR = new RectF();
-
+
private static final Matrix.ScaleToFit[] sFits =
new Matrix.ScaleToFit[] {
Matrix.ScaleToFit.FILL,
@@ -44,11 +43,11 @@
Matrix.ScaleToFit.CENTER,
Matrix.ScaleToFit.END
};
-
+
private static final String[] sFitLabels = new String[] {
"FILL", "START", "CENTER", "END"
};
-
+
private static final int[] sSrcData = new int[] {
80, 40, Color.RED,
40, 80, Color.GREEN,
@@ -56,7 +55,7 @@
80, 80, Color.BLACK
};
private static final int N = 4;
-
+
private static final int WIDTH = 52;
private static final int HEIGHT = 52;
private final RectF mDstR = new RectF(0, 0, WIDTH, HEIGHT);
@@ -67,34 +66,33 @@
mHairPaint.setStyle(Paint.Style.STROKE);
mLabelPaint.setTextSize(16);
}
-
+
private void setSrcR(int index) {
int w = sSrcData[index*3 + 0];
int h = sSrcData[index*3 + 1];
mSrcR.set(0, 0, w, h);
}
-
+
private void drawSrcR(Canvas canvas, int index) {
mPaint.setColor(sSrcData[index*3 + 2]);
canvas.drawOval(mSrcR, mPaint);
}
-
+
private void drawFit(Canvas canvas, int index, Matrix.ScaleToFit stf) {
canvas.save();
-
+
setSrcR(index);
mMatrix.setRectToRect(mSrcR, mDstR, stf);
canvas.concat(mMatrix);
drawSrcR(canvas, index);
-
+
canvas.restore();
-
+
canvas.drawRect(mDstR, mHairPaint);
}
- @Override protected void onDraw(Canvas canvas) {
- Paint paint = mPaint;
-
+ @Override
+ protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.translate(10, 10);
@@ -106,7 +104,7 @@
canvas.translate(mSrcR.width() + 15, 0);
}
canvas.restore();
-
+
canvas.translate(0, 100);
for (int j = 0; j < sFits.length; j++) {
canvas.save();
@@ -121,4 +119,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java b/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
index 87e0461..dc07a27 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/SensorTest.java
@@ -24,6 +24,7 @@
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Config;
+import android.util.Log;
import android.view.View;
public class SensorTest extends GraphicsActivity {
@@ -33,7 +34,7 @@
private Sensor mSensor;
private SampleView mView;
private float[] mValues;
-
+
private static class RunAve {
private final float[] mWeights;
private final float mWeightScale;
@@ -43,7 +44,7 @@
public RunAve(float[] weights) {
mWeights = weights;
-
+
float sum = 0;
for (int i = 0; i < weights.length; i++) {
sum += weights[i];
@@ -54,12 +55,12 @@
mSamples = new float[mDepth];
mCurr = 0;
}
-
+
public void addSample(float value) {
mSamples[mCurr] = value;
mCurr = (mCurr + 1) % mDepth;
}
-
+
public float computeAve() {
final int depth = mDepth;
int index = mCurr;
@@ -92,20 +93,20 @@
}
mPrev[i] = event.values[i];
}
-
+
if (show) {
// only shows if we think the delta is big enough, in an attempt
// to detect "serious" moves left/right or up/down
- android.util.Log.e(TAG, "sensorChanged " + event.sensor.getName() +
+ Log.e(TAG, "sensorChanged " + event.sensor.getName() +
" (" + event.values[0] + ", " + event.values[1] + ", " +
event.values[2] + ")" + " diff(" + diff[0] +
" " + diff[1] + " " + diff[2] + ")");
}
-
+
long now = android.os.SystemClock.uptimeMillis();
if (now - mLastGestureTime > 1000) {
mLastGestureTime = 0;
-
+
float x = diff[0];
float y = diff[1];
boolean gestX = Math.abs(x) > 3;
@@ -114,15 +115,15 @@
if ((gestX || gestY) && !(gestX && gestY)) {
if (gestX) {
if (x < 0) {
- android.util.Log.e("test", "<<<<<<<< LEFT <<<<<<<<<<<<");
+ Log.e("test", "<<<<<<<< LEFT <<<<<<<<<<<<");
} else {
- android.util.Log.e("test", ">>>>>>>>> RITE >>>>>>>>>>>");
+ Log.e("test", ">>>>>>>>> RITE >>>>>>>>>>>");
}
} else {
if (y < -2) {
- android.util.Log.e("test", "<<<<<<<< UP <<<<<<<<<<<<");
+ Log.e("test", "<<<<<<<< UP <<<<<<<<<<<<");
} else {
- android.util.Log.e("test", ">>>>>>>>> DOWN >>>>>>>>>>>");
+ Log.e("test", ">>>>>>>>> DOWN >>>>>>>>>>>");
}
}
mLastGestureTime = now;
@@ -141,28 +142,27 @@
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mView = new SampleView(this);
setContentView(mView);
- if (Config.LOGD) android.util.Log.d(TAG, "create " + mSensorManager);
+ if (Config.DEBUG) Log.d(TAG, "create " + mSensorManager);
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_FASTEST);
- if (Config.LOGD) android.util.Log.d(TAG, "resume " + mSensorManager);
+ if (Config.DEBUG) Log.d(TAG, "resume " + mSensorManager);
}
-
+
@Override
protected void onStop() {
mSensorManager.unregisterListener(mListener);
super.onStop();
- if (Config.LOGD) android.util.Log.d(TAG, "stop " + mSensorManager);
+ if (Config.DEBUG) Log.d(TAG, "stop " + mSensorManager);
}
private class SampleView extends View {
private Paint mPaint = new Paint();
private Path mPath = new Path();
private boolean mAnimate;
- private long mNextTime;
public SampleView(Context context) {
super(context);
@@ -174,13 +174,13 @@
mPath.lineTo(20, 60);
mPath.close();
}
-
+
@Override
protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(Color.WHITE);
-
+
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
@@ -191,21 +191,23 @@
int cy = h / 2;
canvas.translate(cx, cy);
- if (mValues != null) {
+ if (mValues != null) {
canvas.rotate(-mValues[0]);
}
canvas.drawPath(mPath, mPaint);
}
-
+
@Override
protected void onAttachedToWindow() {
mAnimate = true;
+ if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate="+mAnimate);
super.onAttachedToWindow();
}
-
+
@Override
protected void onDetachedFromWindow() {
mAnimate = false;
+ if (Config.DEBUG) Log.d(TAG, "onAttachedToWindow. mAnimate="+mAnimate);
super.onDetachedFromWindow();
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java b/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
index 6d450bb..236f4fc 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/ShapeDrawable1.java
@@ -16,16 +16,12 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class ShapeDrawable1 extends GraphicsActivity {
@@ -35,49 +31,49 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private ShapeDrawable[] mDrawables;
-
+
private static Shader makeSweep() {
return new SweepGradient(150, 25,
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 },
null);
}
-
+
private static Shader makeLinear() {
return new LinearGradient(0, 0, 50, 50,
new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF },
null, Shader.TileMode.MIRROR);
}
-
+
private static Shader makeTiling() {
int[] pixels = new int[] { 0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0};
Bitmap bm = Bitmap.createBitmap(pixels, 2, 2,
Bitmap.Config.ARGB_8888);
-
+
return new BitmapShader(bm, Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT);
}
-
+
private static class MyShapeDrawable extends ShapeDrawable {
private Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
+
public MyShapeDrawable(Shape s) {
super(s);
mStrokePaint.setStyle(Paint.Style.STROKE);
}
-
+
public Paint getStrokePaint() {
return mStrokePaint;
}
-
+
@Override protected void onDraw(Shape s, Canvas c, Paint p) {
s.draw(c, p);
s.draw(c, mStrokePaint);
}
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
@@ -85,14 +81,14 @@
float[] outerR = new float[] { 12, 12, 12, 12, 0, 0, 0, 0 };
RectF inset = new RectF(6, 6, 6, 6);
float[] innerR = new float[] { 12, 12, 0, 0, 12, 12, 0, 0 };
-
+
Path path = new Path();
path.moveTo(50, 0);
path.lineTo(0, 50);
path.lineTo(50, 100);
path.lineTo(100, 50);
path.close();
-
+
mDrawables = new ShapeDrawable[7];
mDrawables[0] = new ShapeDrawable(new RectShape());
mDrawables[1] = new ShapeDrawable(new OvalShape());
@@ -104,7 +100,7 @@
innerR));
mDrawables[5] = new ShapeDrawable(new PathShape(path, 100, 100));
mDrawables[6] = new MyShapeDrawable(new ArcShape(45, -270));
-
+
mDrawables[0].getPaint().setColor(0xFFFF0000);
mDrawables[1].getPaint().setColor(0xFF00FF00);
mDrawables[2].getPaint().setColor(0xFF0000FF);
@@ -112,26 +108,26 @@
mDrawables[4].getPaint().setShader(makeLinear());
mDrawables[5].getPaint().setShader(makeTiling());
mDrawables[6].getPaint().setColor(0x88FF8844);
-
+
PathEffect pe = new DiscretePathEffect(10, 4);
PathEffect pe2 = new CornerPathEffect(4);
mDrawables[3].getPaint().setPathEffect(
new ComposePathEffect(pe2, pe));
-
+
MyShapeDrawable msd = (MyShapeDrawable)mDrawables[6];
msd.getStrokePaint().setStrokeWidth(4);
}
-
+
@Override protected void onDraw(Canvas canvas) {
-
+
int x = 10;
int y = 10;
int width = 300;
int height = 50;
-
+
for (Drawable dr : mDrawables) {
dr.setBounds(x, y, x + width, y + height);
- dr.draw(canvas);
+ dr.draw(canvas);
y += height + 5;
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
index dc127fd..5da10cf 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Sweep.java
@@ -16,11 +16,6 @@
package com.example.android.apis.graphics;
-// Need the following import to get access to the app resources, since this
-// class is in a sub-package.
-//import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -34,7 +29,7 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float mRotate;
@@ -55,7 +50,7 @@
Color.GREEN }, null);
mPaint.setShader(mShader);
}
-
+
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
float x = 160;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
index 0576a7c..0ecba16 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TextAlign.java
@@ -16,13 +16,9 @@
package com.example.android.apis.graphics;
-import com.example.android.apis.R;
-
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
public class TextAlign extends GraphicsActivity {
@@ -32,27 +28,27 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint;
private float mX;
private float[] mPos;
-
+
private Path mPath;
private Paint mPathPaint;
-
+
private static final int DY = 30;
private static final String TEXT_L = "Left";
private static final String TEXT_C = "Center";
private static final String TEXT_R = "Right";
private static final String POSTEXT = "Positioned";
private static final String TEXTONPATH = "Along a path";
-
+
private static void makePath(Path p) {
p.moveTo(10, 0);
p.cubicTo(100, -50, 200, 50, 300, 0);
}
-
+
private float[] buildTextPositions(String text, float y, Paint paint) {
float[] widths = new float[text.length()];
// initially get the widths for each char
@@ -67,18 +63,18 @@
}
return pos;
}
-
+
public SampleView(Context context) {
super(context);
setFocusable(true);
-
+
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(30);
mPaint.setTypeface(Typeface.SERIF);
-
+
mPos = buildTextPositions(POSTEXT, 0, mPaint);
-
+
mPath = new Path();
makePath(mPath);
@@ -87,7 +83,7 @@
mPathPaint.setColor(0x800000FF);
mPathPaint.setStyle(Paint.Style.STROKE);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
@@ -95,13 +91,13 @@
float x = mX;
float y = 0;
float[] pos = mPos;
-
+
// draw the normal strings
p.setColor(0x80FF0000);
canvas.drawLine(x, y, x, y+DY*3, p);
p.setColor(Color.BLACK);
-
+
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.LEFT);
canvas.drawText(TEXT_L, x, y, p);
@@ -113,11 +109,11 @@
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(TEXT_R, x, y, p);
-
+
canvas.translate(100, DY*2);
// now draw the positioned strings
-
+
p.setColor(0xBB00FF00);
for (int i = 0; i < pos.length/2; i++) {
canvas.drawLine(pos[i*2+0], pos[i*2+1]-DY,
@@ -127,17 +123,17 @@
p.setTextAlign(Paint.Align.LEFT);
canvas.drawPosText(POSTEXT, pos, p);
-
+
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.CENTER);
canvas.drawPosText(POSTEXT, pos, p);
-
+
canvas.translate(0, DY);
p.setTextAlign(Paint.Align.RIGHT);
canvas.drawPosText(POSTEXT, pos, p);
-
+
// now draw the text on path
-
+
canvas.translate(-100, DY*2);
canvas.drawPath(mPath, mPathPaint);
@@ -148,7 +144,7 @@
canvas.drawPath(mPath, mPathPaint);
p.setTextAlign(Paint.Align.CENTER);
canvas.drawTextOnPath(TEXTONPATH, mPath, 0, 0, p);
-
+
canvas.translate(0, DY*1.5f);
canvas.drawPath(mPath, mPathPaint);
p.setTextAlign(Paint.Align.RIGHT);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
index 14e6c4f..9a3eb65 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -41,34 +40,34 @@
public class TouchPaint extends GraphicsActivity {
/** Used as a pulse to gradually fade the contents of the window. */
private static final int FADE_MSG = 1;
-
+
/** Menu ID for the command to clear the window. */
private static final int CLEAR_ID = Menu.FIRST;
/** Menu ID for the command to toggle fading. */
private static final int FADE_ID = Menu.FIRST+1;
-
+
/** How often to fade the contents of the window (in ms). */
private static final int FADE_DELAY = 100;
-
+
/** The view responsible for drawing the window. */
MyView mView;
/** Is fading mode enabled? */
boolean mFading;
-
+
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+
// Create and attach the view that is responsible for painting.
mView = new MyView(this);
setContentView(mView);
mView.requestFocus();
-
+
// Restore the fading option if we are being thawed from a
// previously saved state. Note that we are not currently remembering
// the contents of the bitmap.
mFading = savedInstanceState != null ? savedInstanceState.getBoolean("fading", true) : true;
}
-
+
@Override public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, CLEAR_ID, 0, "Clear");
menu.add(0, FADE_ID, 0, "Fade").setCheckable(true);
@@ -130,14 +129,14 @@
mHandler.sendMessageDelayed(
mHandler.obtainMessage(FADE_MSG), FADE_DELAY);
}
-
+
/**
* Stop the pulse to fade the screen.
*/
void stopFading() {
mHandler.removeMessages(FADE_MSG);
}
-
+
private Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
@@ -155,7 +154,7 @@
}
}
};
-
+
public class MyView extends View {
private static final int FADE_ALPHA = 0x06;
private static final int MAX_FADE_STEPS = 256/FADE_ALPHA + 4;
@@ -169,7 +168,7 @@
private float mCurX;
private float mCurY;
private int mFadeSteps = MAX_FADE_STEPS;
-
+
public MyView(Context c) {
super(c);
setFocusable(true);
@@ -189,7 +188,7 @@
mFadeSteps = MAX_FADE_STEPS;
}
}
-
+
public void fade() {
if (mCanvas != null && mFadeSteps < MAX_FADE_STEPS) {
mCanvas.drawPaint(mFadePaint);
@@ -197,7 +196,7 @@
mFadeSteps++;
}
}
-
+
@Override protected void onSizeChanged(int w, int h, int oldw,
int oldh) {
int curW = mBitmap != null ? mBitmap.getWidth() : 0;
@@ -205,10 +204,10 @@
if (curW >= w && curH >= h) {
return;
}
-
+
if (curW < w) curW = w;
if (curH < h) curH = h;
-
+
Bitmap newBitmap = Bitmap.createBitmap(curW, curH,
Bitmap.Config.RGB_565);
Canvas newCanvas = new Canvas();
@@ -220,7 +219,7 @@
mCanvas = newCanvas;
mFadeSteps = MAX_FADE_STEPS;
}
-
+
@Override protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
canvas.drawBitmap(mBitmap, 0, 0, null);
@@ -246,7 +245,7 @@
drawPoint(mCurX, mCurY, 1.0f, 16.0f);
return true;
}
-
+
@Override public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
if (action != MotionEvent.ACTION_UP && action != MotionEvent.ACTION_CANCEL) {
@@ -269,7 +268,7 @@
}
return true;
}
-
+
private void drawPoint(float x, float y, float pressure, float width) {
//Log.i("TouchPaint", "Drawing: " + x + "x" + y + " p="
// + pressure + " width=" + width);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
index c0f32a7..4133c04 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
index ede6ef5..c41d173 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
@@ -23,7 +23,6 @@
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
-import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
index aefc311..08facaa 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Typefaces.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,20 +28,20 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Typeface mFace;
-
+
public SampleView(Context context) {
super(context);
mFace = Typeface.createFromAsset(getContext().getAssets(),
"fonts/samplefont.ttf");
-
+
mPaint.setTextSize(64);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java b/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
index 7ee99d0..0a2f630 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/UnicodeChart.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
@@ -29,20 +28,20 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+
requestWindowFeature(Window.FEATURE_NO_TITLE);
-
+
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private Paint mBigCharPaint;
private Paint mLabelPaint;
private final char[] mChars = new char[256];
private final float[] mPos = new float[512];
-
+
private int mBase;
-
+
private static final int XMUL = 20;
private static final int YMUL = 28;
private static final int YBASE = 18;
@@ -51,49 +50,49 @@
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
-
+
mBigCharPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBigCharPaint.setTextSize(15);
mBigCharPaint.setTextAlign(Paint.Align.CENTER);
-
+
mLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLabelPaint.setTextSize(8);
mLabelPaint.setTextAlign(Paint.Align.CENTER);
-
+
// the position array is the same for all charts
float[] pos = mPos;
int index = 0;
for (int col = 0; col < 16; col++) {
- final float x = col * 20 + 10;
+ final float x = col * XMUL + 10;
for (int row = 0; row < 16; row++) {
pos[index++] = x;
pos[index++] = row * YMUL + YBASE;
}
}
}
-
+
private float computeX(int index) {
- return (index >> 4) * 20 + 10;
+ return (index >> 4) * XMUL + 10;
}
private float computeY(int index) {
return (index & 0xF) * YMUL + YMUL;
}
-
+
private void drawChart(Canvas canvas, int base) {
char[] chars = mChars;
for (int i = 0; i < 256; i++) {
int unichar = base + i;
chars[i] = (char)unichar;
-
+
canvas.drawText(Integer.toHexString(unichar),
computeX(i), computeY(i), mLabelPaint);
}
canvas.drawPosText(chars, 0, 256, mPos, mBigCharPaint);
}
-
+
@Override protected void onDraw(Canvas canvas) {
- canvas.drawColor(Color.WHITE);
+ canvas.drawColor(Color.WHITE);
canvas.translate(0, 1);
drawChart(canvas, mBase * 256);
@@ -118,4 +117,3 @@
}
}
}
-
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
index 1e61906..ac1ab8a 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Vertices.java
@@ -18,17 +18,11 @@
import com.example.android.apis.R;
-import android.app.Activity;
import android.content.Context;
import android.graphics.*;
-import android.graphics.drawable.*;
import android.os.Bundle;
-import android.view.KeyEvent;
import android.view.*;
-import java.io.IOException;
-import java.io.InputStream;
-
public class Vertices extends GraphicsActivity {
@Override
@@ -36,14 +30,13 @@
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private final Paint mPaint = new Paint();
private final float[] mVerts = new float[10];
private final float[] mTexs = new float[10];
- private final int[] mColors = new int[10];
private final short[] mIndices = { 0, 1, 2, 3, 4, 1 };
-
+
private final Matrix mMatrix = new Matrix();
private final Matrix mInverse = new Matrix();
@@ -61,7 +54,7 @@
Shader s = new BitmapShader(bm, Shader.TileMode.CLAMP,
Shader.TileMode.CLAMP);
mPaint.setShader(s);
-
+
float w = bm.getWidth();
float h = bm.getHeight();
// construct our mesh
@@ -70,18 +63,18 @@
setXY(mTexs, 2, w, 0);
setXY(mTexs, 3, w, h);
setXY(mTexs, 4, 0, h);
-
+
setXY(mVerts, 0, w/2, h/2);
setXY(mVerts, 1, 0, 0);
setXY(mVerts, 2, w, 0);
setXY(mVerts, 3, w, h);
setXY(mVerts, 4, 0, h);
-
+
mMatrix.setScale(0.8f, 0.8f);
mMatrix.preTranslate(20, 20);
mMatrix.invert(mInverse);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);
canvas.save();
@@ -104,7 +97,7 @@
invalidate();
return true;
}
-
+
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java b/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
index b9f8424..54e15e3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java
@@ -16,7 +16,6 @@
package com.example.android.apis.graphics;
-import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
@@ -33,35 +32,35 @@
import android.view.View;
public class Xfermodes extends GraphicsActivity {
-
+
// create a bitmap with a circle, used for the "dst" image
static Bitmap makeDst(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
- p.setColor(0xFFFFCC44);
+
+ p.setColor(0xFFFFCC44);
c.drawOval(new RectF(0, 0, w*3/4, h*3/4), p);
return bm;
}
-
+
// create a bitmap with a rect, used for the "src" image
static Bitmap makeSrc(int w, int h) {
Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
+
p.setColor(0xFF66AAFF);
c.drawRect(w/3, h/3, w*19/20, h*19/20, p);
return bm;
}
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
-
+
private static class SampleView extends View {
private static final int W = 64;
private static final int H = 64;
@@ -70,7 +69,7 @@
private Bitmap mSrcB;
private Bitmap mDstB;
private Shader mBG; // background checker-board pattern
-
+
private static final Xfermode[] sModes = {
new PorterDuffXfermode(PorterDuff.Mode.CLEAR),
new PorterDuffXfermode(PorterDuff.Mode.SRC),
@@ -89,20 +88,20 @@
new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY),
new PorterDuffXfermode(PorterDuff.Mode.SCREEN)
};
-
+
private static final String[] sLabels = {
"Clear", "Src", "Dst", "SrcOver",
"DstOver", "SrcIn", "DstIn", "SrcOut",
"DstOut", "SrcATop", "DstATop", "Xor",
"Darken", "Lighten", "Multiply", "Screen"
};
-
+
public SampleView(Context context) {
super(context);
-
+
mSrcB = makeSrc(W, H);
mDstB = makeDst(W, H);
-
+
// make a ckeckerboard pattern
Bitmap bm = Bitmap.createBitmap(new int[] { 0xFFFFFFFF, 0xFFCCCCCC,
0xFFCCCCCC, 0xFFFFFFFF }, 2, 2,
@@ -114,18 +113,18 @@
m.setScale(6, 6);
mBG.setLocalMatrix(m);
}
-
+
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
-
+
Paint labelP = new Paint(Paint.ANTI_ALIAS_FLAG);
labelP.setTextAlign(Paint.Align.CENTER);
-
+
Paint paint = new Paint();
paint.setFilterBitmap(false);
-
+
canvas.translate(15, 35);
-
+
int x = 0;
int y = 0;
for (int i = 0; i < sModes.length; i++) {
@@ -134,12 +133,12 @@
paint.setShader(null);
canvas.drawRect(x - 0.5f, y - 0.5f,
x + W + 0.5f, y + H + 0.5f, paint);
-
+
// draw the checker-board pattern
paint.setStyle(Paint.Style.FILL);
paint.setShader(mBG);
canvas.drawRect(x, y, x + W, y + H, paint);
-
+
// draw the src/dst example into our offscreen bitmap
int sc = canvas.saveLayer(x, y, x + W, y + H, null,
Canvas.MATRIX_SAVE_FLAG |
@@ -153,13 +152,13 @@
canvas.drawBitmap(mSrcB, 0, 0, paint);
paint.setXfermode(null);
canvas.restoreToCount(sc);
-
+
// draw the label
canvas.drawText(sLabels[i],
x + W/2, y - labelP.getTextSize()/2, labelP);
-
+
x += W + 10;
-
+
// wrap around when we've drawn enough for one row
if ((i % ROW_MAX) == ROW_MAX - 1) {
x = 0;
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
index b2236aa..041794e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation2.java
@@ -49,7 +49,7 @@
s.setOnItemSelectedListener(this);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
switch (position) {
case 0:
@@ -79,7 +79,7 @@
}
}
- public void onNothingSelected(AdapterView parent) {
+ public void onNothingSelected(AdapterView<?> parent) {
}
private String[] mStrings = {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
index 11fc9ed..2cd7605 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
@@ -50,7 +50,7 @@
s.setOnItemSelectedListener(this);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
final View target = findViewById(R.id.target);
final View targetParent = (View) target.getParent();
@@ -96,6 +96,6 @@
target.startAnimation(a);
}
- public void onNothingSelected(AdapterView parent) {
+ public void onNothingSelected(AdapterView<?> parent) {
}
}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
index f4274e5..bec4a5d 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.java
@@ -19,12 +19,9 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.os.Bundle;
-import android.view.View;
-
public class AutoComplete1 extends Activity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
index c6fa08b..3d63a91 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.java
@@ -22,13 +22,15 @@
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
-import android.provider.Contacts;
+import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AutoCompleteTextView;
import android.widget.CursorAdapter;
+import android.widget.FilterQueryProvider;
import android.widget.Filterable;
import android.widget.TextView;
@@ -39,8 +41,9 @@
setContentView(R.layout.autocomplete_4);
ContentResolver content = getContentResolver();
- Cursor cursor = content.query(Contacts.People.CONTENT_URI,
- PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
+ Cursor cursor = content.query(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
+
ContactListAdapter adapter = new ContactListAdapter(this, cursor);
AutoCompleteTextView textView = (AutoCompleteTextView)
@@ -61,50 +64,40 @@
final LayoutInflater inflater = LayoutInflater.from(context);
final TextView view = (TextView) inflater.inflate(
android.R.layout.simple_dropdown_item_1line, parent, false);
- view.setText(cursor.getString(5));
+ view.setText(cursor.getString(COLUMN_DISPLAY_NAME));
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
- ((TextView) view).setText(cursor.getString(5));
+ ((TextView) view).setText(cursor.getString(COLUMN_DISPLAY_NAME));
}
@Override
public String convertToString(Cursor cursor) {
- return cursor.getString(5);
+ return cursor.getString(COLUMN_DISPLAY_NAME);
}
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
- if (getFilterQueryProvider() != null) {
- return getFilterQueryProvider().runQuery(constraint);
+ FilterQueryProvider filter = getFilterQueryProvider();
+ if (filter != null) {
+ return filter.runQuery(constraint);
}
- StringBuilder buffer = null;
- String[] args = null;
- if (constraint != null) {
- buffer = new StringBuilder();
- buffer.append("UPPER(");
- buffer.append(Contacts.ContactMethods.NAME);
- buffer.append(") GLOB ?");
- args = new String[] { constraint.toString().toUpperCase() + "*" };
- }
-
- return mContent.query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION,
- buffer == null ? null : buffer.toString(), args,
- Contacts.People.DEFAULT_SORT_ORDER);
+ Uri uri = Uri.withAppendedPath(
+ Contacts.CONTENT_FILTER_URI,
+ Uri.encode(constraint.toString()));
+ return mContent.query(uri, CONTACT_PROJECTION, null, null, null);
}
- private ContentResolver mContent;
+ private ContentResolver mContent;
}
- private static final String[] PEOPLE_PROJECTION = new String[] {
- Contacts.People._ID,
- Contacts.People.PRIMARY_PHONE_ID,
- Contacts.People.TYPE,
- Contacts.People.NUMBER,
- Contacts.People.LABEL,
- Contacts.People.NAME,
+ public static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
};
-}
+
+ private static final int COLUMN_DISPLAY_NAME = 1;
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
index 7406da4..2009d8a2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.java
@@ -22,7 +22,7 @@
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
-import android.provider.Contacts;
+import android.provider.ContactsContract.Contacts;
import android.widget.AutoCompleteTextView;
public class AutoComplete5 extends Activity {
@@ -32,8 +32,8 @@
setContentView(R.layout.autocomplete_5);
ContentResolver content = getContentResolver();
- Cursor cursor = content.query(Contacts.People.CONTENT_URI,
- PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
+ Cursor cursor = content.query(Contacts.CONTENT_URI,
+ AutoComplete4.CONTACT_PROJECTION, null, null, null);
AutoComplete4.ContactListAdapter adapter =
new AutoComplete4.ContactListAdapter(this, cursor);
@@ -41,13 +41,4 @@
findViewById(R.id.edit);
textView.setAdapter(adapter);
}
-
- private static final String[] PEOPLE_PROJECTION = new String[] {
- Contacts.People._ID,
- Contacts.People.PRIMARY_PHONE_ID,
- Contacts.People.TYPE,
- Contacts.People.NUMBER,
- Contacts.People.LABEL,
- Contacts.People.NAME
- };
-}
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
index 3573bfb..2c28d65 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.java
@@ -19,12 +19,9 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.MultiAutoCompleteTextView;
import android.os.Bundle;
-import android.view.View;
-
public class AutoComplete6 extends Activity {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java b/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
index e2f8cc8..a88ee30 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.java
@@ -22,9 +22,6 @@
import android.app.Activity;
import android.os.Bundle;
-import android.widget.Spinner;
-import android.widget.ArrayAdapter;
-
/**
* A gallery of the different styles of buttons.
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
index 5784122..b6cce29 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.java
@@ -17,49 +17,49 @@
package com.example.android.apis.view;
import android.app.ExpandableListActivity;
-import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
-import android.net.Uri;
import android.os.Bundle;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.widget.ExpandableListAdapter;
import android.widget.SimpleCursorTreeAdapter;
-
/**
* Demonstrates expandable lists backed by Cursors
*/
public class ExpandableList2 extends ExpandableListActivity {
- private int mGroupIdColumnIndex;
-
- private String mPhoneNumberProjection[] = new String[] {
- People.Phones._ID, People.Phones.NUMBER
+ private static final int COLUMN_CONTACT_ID = 0;
+
+ private static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
};
-
+ private static final String[] PHONE_PROJECTION = new String[] {
+ Phone._ID,
+ Phone.CONTACT_ID,
+ Phone.NUMBER
+ };
+
private ExpandableListAdapter mAdapter;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Query for people
- Cursor groupCursor = managedQuery(People.CONTENT_URI,
- new String[] {People._ID, People.NAME}, null, null, null);
-
- // Cache the ID column index
- mGroupIdColumnIndex = groupCursor.getColumnIndexOrThrow(People._ID);
+ Cursor groupCursor = managedQuery(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
// Set up our adapter
mAdapter = new MyExpandableListAdapter(groupCursor,
this,
android.R.layout.simple_expandable_list_item_1,
android.R.layout.simple_expandable_list_item_1,
- new String[] {People.NAME}, // Name for group layouts
+ new String[] {Contacts.DISPLAY_NAME}, // Name for group layouts
new int[] {android.R.id.text1},
- new String[] {People.NUMBER}, // Number for child layouts
+ new String[] {Phone.NUMBER}, // Number for child layouts
new int[] {android.R.id.text1});
setListAdapter(mAdapter);
}
@@ -75,18 +75,13 @@
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
- // Given the group, we return a cursor for all the children within that group
-
- // Return a cursor that points to this contact's phone numbers
- Uri.Builder builder = People.CONTENT_URI.buildUpon();
- ContentUris.appendId(builder, groupCursor.getLong(mGroupIdColumnIndex));
- builder.appendEncodedPath(People.Phones.CONTENT_DIRECTORY);
- Uri phoneNumbersUri = builder.build();
-
+ int contactId = groupCursor.getInt(COLUMN_CONTACT_ID);
// The returned Cursor MUST be managed by us, so we use Activity's helper
// functionality to manage it for us.
- return managedQuery(phoneNumbersUri, mPhoneNumberProjection, null, null, null);
+ return managedQuery(Phone.CONTENT_URI,
+ PHONE_PROJECTION,
+ Phone.CONTACT_ID + " = " + contactId,
+ null, null);
}
-
}
-}
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java b/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
index 86f6ee7..c816b31 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Focus1.java
@@ -20,12 +20,10 @@
import android.app.Activity;
import android.os.Bundle;
-import android.view.View;
import android.webkit.WebView;
import android.widget.ListView;
import android.widget.ArrayAdapter;
-
/**
* Demonstrates the use of non-focusable views.
*/
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
index a539a5b..7aaaaef 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.java
@@ -49,7 +49,7 @@
// Set a item click listener, and just Toast the clicked position
g.setOnItemClickListener(new OnItemClickListener() {
- public void onItemClick(AdapterView parent, View v, int position, long id) {
+ public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(Gallery1.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java b/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
index 2eea1ff..ed33451 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.java
@@ -17,9 +17,8 @@
package com.example.android.apis.view;
import android.app.Activity;
-import android.content.Context;
import android.database.Cursor;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
import android.os.Bundle;
import android.widget.Gallery;
import android.widget.SimpleCursorAdapter;
@@ -37,16 +36,17 @@
setContentView(R.layout.gallery_2);
// Get a cursor with all people
- Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
+ Cursor c = getContentResolver().query(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
startManagingCursor(c);
-
+
SpinnerAdapter adapter = new SimpleCursorAdapter(this,
// Use a template that displays a text view
android.R.layout.simple_gallery_item,
// Give the cursor to the list adatper
c,
// Map the NAME column in the people database to...
- new String[] {People.NAME},
+ new String[] {Contacts.DISPLAY_NAME},
// The "text1" view defined in the XML template
new int[] { android.R.id.text1 });
@@ -54,4 +54,8 @@
g.setAdapter(adapter);
}
-}
+ private static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
+ };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java b/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
index 66ef282..7f17c82 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.java
@@ -56,11 +56,11 @@
g.setOnItemSelectedListener(this);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
mSwitcher.setImageResource(mImageIds[position]);
}
- public void onNothingSelected(AdapterView parent) {
+ public void onNothingSelected(AdapterView<?> parent) {
}
public View makeView() {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List13.java b/samples/ApiDemos/src/com/example/android/apis/view/List13.java
index b3087be..68179ed 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List13.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List13.java
@@ -52,7 +52,6 @@
private LayoutInflater mInflater;
public SlowAdapter(Context context) {
- mContext = context;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@@ -114,11 +113,6 @@
return text;
}
-
- /**
- * Remember our context so we can use it when constructing views.
- */
- private Context mContext;
}
@Override
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List2.java b/samples/ApiDemos/src/com/example/android/apis/view/List2.java
index 4f37dd8..4dca2a7 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List2.java
@@ -18,34 +18,40 @@
import android.app.ListActivity;
import android.database.Cursor;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;
/**
- * A list view example where the
+ * A list view example where the
* data comes from a cursor.
*/
public class List2 extends ListActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a cursor with all people
- Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
+ Cursor c = getContentResolver().query(Contacts.CONTENT_URI,
+ CONTACT_PROJECTION, null, null, null);
startManagingCursor(c);
- ListAdapter adapter = new SimpleCursorAdapter(this,
+ ListAdapter adapter = new SimpleCursorAdapter(this,
// Use a template that displays a text view
- android.R.layout.simple_list_item_1,
+ android.R.layout.simple_list_item_1,
// Give the cursor to the list adatper
- c,
+ c,
// Map the NAME column in the people database to...
- new String[] {People.NAME} ,
+ new String[] {Contacts.DISPLAY_NAME},
// The "text1" view defined in the XML template
- new int[] {android.R.id.text1});
+ new int[] {android.R.id.text1});
setListAdapter(adapter);
}
-}
+
+ private static final String[] CONTACT_PROJECTION = new String[] {
+ Contacts._ID,
+ Contacts.DISPLAY_NAME
+ };
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List3.java b/samples/ApiDemos/src/com/example/android/apis/view/List3.java
index 17e59f1..9c3b4b4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List3.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List3.java
@@ -16,36 +16,69 @@
package com.example.android.apis.view;
-
import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
-import android.provider.Contacts.Phones;
-import android.widget.ListAdapter;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.view.View;
import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
/**
- * A list view example where the
+ * A list view example where the
* data comes from a cursor, and a
* SimpleCursorListAdapter is used to map each item to a two-line
* display.
*/
public class List3 extends ListActivity {
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get a cursor with all phones
- Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
+ Cursor c = getContentResolver().query(Phone.CONTENT_URI,
+ PHONE_PROJECTION, null, null, null);
startManagingCursor(c);
-
+
// Map Cursor columns to views defined in simple_list_item_2.xml
- ListAdapter adapter = new SimpleCursorAdapter(this,
- android.R.layout.simple_list_item_2, c,
- new String[] { Phones.NAME, Phones.NUMBER },
+ SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
+ android.R.layout.simple_list_item_2, c,
+ new String[] {
+ Phone.TYPE,
+ Phone.NUMBER
+ },
new int[] { android.R.id.text1, android.R.id.text2 });
+ //Used to display a readable string for the phone type
+ adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
+ public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
+ //Let the adapter handle the binding if the column is not TYPE
+ if (columnIndex != COLUMN_TYPE) {
+ return false;
+ }
+ int type = cursor.getInt(COLUMN_TYPE);
+ String label = null;
+ //Custom type? Then get the custom label
+ if (type == Phone.TYPE_CUSTOM) {
+ label = cursor.getString(COLUMN_LABEL);
+ }
+ //Get the readable string
+ String text = (String) Phone.getTypeLabel(getResources(), type, label);
+ //Set text
+ ((TextView) view).setText(text);
+ return true;
+ }
+ });
setListAdapter(adapter);
}
-
-}
+
+ private static final String[] PHONE_PROJECTION = new String[] {
+ Phone._ID,
+ Phone.TYPE,
+ Phone.LABEL,
+ Phone.NUMBER
+ };
+
+ private static final int COLUMN_TYPE = 1;;
+ private static final int COLUMN_LABEL = 2;
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List7.java b/samples/ApiDemos/src/com/example/android/apis/view/List7.java
index e773db6..ff5406f 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List7.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List7.java
@@ -16,12 +16,15 @@
package com.example.android.apis.view;
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
import com.example.android.apis.R;
+
import android.app.ListActivity;
import android.database.Cursor;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.os.Bundle;
-import android.provider.ContactsContract;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
@@ -33,69 +36,64 @@
* A list view example where the data comes from a cursor.
*/
public class List7 extends ListActivity implements OnItemSelectedListener {
- private static final String[] PROJECTION = new String[] {
- ContactsContract.Contacts._ID,
- ContactsContract.Contacts.DISPLAY_NAME,
- ContactsContract.Contacts.HAS_PHONE_NUMBER,
- ContactsContract.Contacts.LOOKUP_KEY
- };
-
- private int mIdColumnIndex;
- private int mHasPhoneColumnIndex;
private TextView mPhone;
+ private static final String[] PHONE_PROJECTION = new String[] {
+ Phone._ID,
+ Phone.TYPE,
+ Phone.LABEL,
+ Phone.NUMBER,
+ Phone.DISPLAY_NAME
+ };
+
+ private static final int COLUMN_PHONE_TYPE = 1;
+ private static final int COLUMN_PHONE_LABEL = 2;
+ private static final int COLUMN_PHONE_NUMBER = 3;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
setContentView(R.layout.list_7);
-
mPhone = (TextView) findViewById(R.id.phone);
getListView().setOnItemSelectedListener(this);
- // Get a cursor with all people
- Cursor c = managedQuery(ContactsContract.Contacts.CONTENT_URI,
- PROJECTION, null, null, null);
- mIdColumnIndex = c.getColumnIndex(ContactsContract.Contacts._ID);
- mHasPhoneColumnIndex = c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
+ // Get a cursor with all numbers.
+ // This query will only return contacts with phone numbers
+ Cursor c = getContentResolver().query(Phone.CONTENT_URI,
+ PHONE_PROJECTION, Phone.NUMBER + " NOT NULL", null, null);
+ startManagingCursor(c);
ListAdapter adapter = new SimpleCursorAdapter(this,
- android.R.layout.simple_list_item_1, // Use a template
- // that displays a
- // text view
- c, // Give the cursor to the list adapter
- new String[] { ContactsContract.Contacts.DISPLAY_NAME }, // Map the NAME column in the
- // people database to...
- new int[] { android.R.id.text1 }); // The "text1" view defined in
- // the XML template
+ // Use a template that displays a text view
+ android.R.layout.simple_list_item_1,
+ // Give the cursor to the list adapter
+ c,
+ // Map the DISPLAY_NAME column to...
+ new String[] {Phone.DISPLAY_NAME},
+ // The "text1" view defined in the XML template
+ new int[] {android.R.id.text1});
setListAdapter(adapter);
}
- public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
if (position >= 0) {
- final Cursor c = (Cursor) parent.getItemAtPosition(position);
- if (c.getInt(mHasPhoneColumnIndex) > 0) {
- final long contactId = c.getLong(mIdColumnIndex);
- final Cursor phones = getContentResolver().query(
- ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
- new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER },
- ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null,
- ContactsContract.CommonDataKinds.Phone.IS_SUPER_PRIMARY + " DESC");
-
- try {
- phones.moveToFirst();
- mPhone.setText(phones.getString(0));
- } finally {
- phones.close();
- }
- } else {
- mPhone.setText(R.string.list_7_nothing);
+ //Get current cursor
+ Cursor c = (Cursor) parent.getItemAtPosition(position);
+ int type = c.getInt(COLUMN_PHONE_TYPE);
+ String phone = c.getString(COLUMN_PHONE_NUMBER);
+ String label = null;
+ //Custom type? Then get the custom label
+ if (type == Phone.TYPE_CUSTOM) {
+ label = c.getString(COLUMN_PHONE_LABEL);
}
+ //Get the readable string
+ String numberType = (String) Phone.getTypeLabel(getResources(), type, label);
+ String text = numberType + ": " + phone;
+ mPhone.setText(text);
}
}
- public void onNothingSelected(AdapterView parent) {
- mPhone.setText(R.string.list_7_nothing);
+ public void onNothingSelected(AdapterView<?> parent) {
}
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/List9.java b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
index 15b3cc1..b2aea05 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/List9.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/List9.java
@@ -111,8 +111,8 @@
- public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
- int lastItem = firstVisibleItem + visibleItemCount - 1;
+ public void onScroll(AbsListView view, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
if (mReady) {
char firstLetter = mStrings[firstVisibleItem].charAt(0);
@@ -120,8 +120,6 @@
mShowing = true;
mDialogText.setVisibility(View.VISIBLE);
-
-
}
mDialogText.setText(((Character)firstLetter).toString());
mHandler.removeCallbacks(mRemoveWindow);
@@ -316,5 +314,4 @@
"Woodside Cabecou", "Xanadu", "Xynotyro", "Yarg Cornish",
"Yarra Valley Pyramid", "Yorkshire Blue", "Zamorano",
"Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
-
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java b/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
index 97416d4..5fbf6dd 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.java
@@ -19,7 +19,6 @@
import android.app.Activity;
import android.os.Bundle;
import android.widget.RatingBar;
-import android.widget.SeekBar;
import android.widget.TextView;
import com.example.android.apis.R;
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
index 1af3c81..02fcd0e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.java
@@ -24,7 +24,6 @@
import android.widget.TextView;
import android.widget.Button;
-
/**
* Demonstrates wrapping a layout in a ScrollView.
*
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
index f1f8f24..f904f84 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.java
@@ -19,15 +19,9 @@
import com.example.android.apis.R;
import android.app.Activity;
-import android.widget.TableLayout;
-import android.widget.Button;
import android.os.Bundle;
-import android.view.View;
-
public class TableLayout10 extends Activity {
- private boolean mShrink;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
index 770238f..09b19a2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.java
@@ -25,8 +25,6 @@
* <p>This example shows how to use horizontal gravity in a table layout.</p>
*/
public class TableLayout11 extends Activity {
- private boolean mShrink;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
index 14cbd0d..f3fe850 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.java
@@ -25,8 +25,6 @@
* <p>This example shows how to use cell spanning in a table layout.</p>
*/
public class TableLayout12 extends Activity {
- private boolean mShrink;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java b/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
index 455969e..39f7e9b 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.java
@@ -21,7 +21,6 @@
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.view.LayoutInflater;
-import android.view.View;
import com.example.android.apis.R;
diff --git a/samples/BrowserPlugin/Android.mk b/samples/BrowserPlugin/Android.mk
deleted file mode 100644
index 827700f..0000000
--- a/samples/BrowserPlugin/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2009 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.
-#
-
-TOP_LOCAL_PATH:= $(call my-dir)
-
-# Build application
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_PACKAGE_NAME := SampleBrowserPlugin
-
-LOCAL_JNI_SHARED_LIBRARIES := libsampleplugin
-
-include $(BUILD_PACKAGE)
-
-# ============================================================
-
-# Also build all of the sub-targets under this one: the shared library.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/BrowserPlugin/AndroidManifest.xml b/samples/BrowserPlugin/AndroidManifest.xml
deleted file mode 100644
index d926729..0000000
--- a/samples/BrowserPlugin/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.sampleplugin"
- android:versionCode="1"
- android:versionName="1.0">
-
- <uses-permission android:name="android.webkit.permission.PLUGIN"/>
-
- <uses-sdk android:minSdkVersion="3" />
-
- <application android:icon="@drawable/sample_browser_plugin"
- android:label="@string/sample_browser_plugin">
- <service android:name=".SamplePlugin">
- <intent-filter>
- <action android:name="android.webkit.PLUGIN" />
- </intent-filter>
- <meta-data android:name="type" android:value="native" />
- </service>
- </application>
-
-</manifest>
diff --git a/samples/BrowserPlugin/MODULE_LICENSE_APACHE2 b/samples/BrowserPlugin/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/samples/BrowserPlugin/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/samples/BrowserPlugin/NOTICE b/samples/BrowserPlugin/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/samples/BrowserPlugin/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/samples/BrowserPlugin/README b/samples/BrowserPlugin/README
deleted file mode 100644
index 29797b2..0000000
--- a/samples/BrowserPlugin/README
+++ /dev/null
@@ -1,177 +0,0 @@
-# Copyright (C) 2009 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.
-#
-
-##############################
-######### CONTENTS ###########
-A. INTRODUCTION
-B. PLUGIN STRUCTURE
-C. HOW TO DEPLOY
-D. SUB-PLUGINS
- 1. ANIMATION
- 2. AUDIO
- 3. BACKGROUND
- 4. FORM
- 5. PAINT
-
-
-##############################
-## (A) INTRODUCTION ##########
-
-The sample plugin is intended to give plugin developers a point of reference to
-see how an android browser plugin is created and how to use the available APIs.
-A plugin is packaged like a standard apk and can be installed either via the
-market or adb. The sample plugin attempts to exercise as many of the APIs as
-possible but unfortunately not all are covered.
-
-Trying to have a single plugin demonstrate all possible API interactions on one
-screen was not practical. On the other hand we also didn't want a separate
-plugin for each interction, as that would result in many separate apk's that
-would need to be maintained. To solve this problem we developed the idea to use
-"sub-plugins". With a sub-plugin only one specific feature of the plugin would
-be active at a time, but they would all share as much common code as possible.
-A detailed description of each sub-plugin and its function can be found in the
-sub-plugins section.
-
-##############################
-## (B) PLUGIN STRUCTURE ######
-
-The sample plugin is packaged as one plugin but contains many unique sub-plugins
-(e.g. audio and paint). The package consists of two pieces: (1) Java code
-containing the config; (2) C++ shared library containing the brower/plugin
-bindings and the sub-plugin classes.
-
-~~~~ (1) JAVA ~~~~~
-Android.mk: specifies the name of the APK (SampleBrowserPlugin) as well as which
- shared libraries to include.
-
-AndroidManifest.xml: similar to a standard android manifest file, except that it
- must contain the "uses-permission" and "service"
- elements that are plugin specific. The "service" element
- contains sub-elements that describe the java component of
- the service.
-
-src/*: location of the java source files. This contains the SamplePlugin.class
- which is the java component of our plugin. The component must exist and
- implement the required interfaces, though simply returning null is valid.
-
-res/*: location of the static resources (e.g. an icon for the plugin)
-
-~~~~ (2) C++ ~~~~~
-jni/Android.mk: specifies the build parameters for the shared library that is to
- be included with the apk. The library contains all the bindings
- between the plugin and the browser.
-
-jni/main.*: this code is the binding point between the plugin and the browser.
- It supports all of the functions required for a standard netscape
- style plugin as well as all the android specific APIs. The initial
- starting point for the plugin is the NP_Initialize function. The
- NPP_New function is responsible for reading the input args and
- selecting the appropriate sub-plugin to instantiate. Most other
- functions either return fixed values or pass their inputs to the
- sub-plugin for processing.
-
-jni/PluginObject.*: The pluginObject provides a convenient container in which to
- store variables (the plugin's state). This objects two main
- responsibilities are (1) to construct and store the NPClass
- object (done using code provided by Apple) and (2) provide
- the abstract class for the sub-plugin objects and a place to
- store the sub-plugin after it is instantiated.
-
-jni/*/*: Each of the sub-plugins has a folder that contains its class definition
- and logic. The sub-plugin receives events from the browser and it can
- also communicate with the browser using the netscape plugin functions
- as well as the specialized android interfaces.
-
-
-##############################
-## (C) HOW TO DEPLOY #########
-
-To compile and install a plugin on a device/emulator simply...
-
-1. run "make SampleBrowserPlugin" (compiles libsampleplugin.so and builds the apk)
-2. the previous command produces an apk file so record its location
-3. run "adb install [apk_file]" to install it on a device/emulator
-4. the browser will auto recognize the plugin is available
-
-Now that the plugin is installed you can manage it just like you would any other
-application via Settings -> Applications -> Manage applications. To execute the
-plugin you need to include an html snippet (similar to the one found below) in
-a document that is accessible by the browser. The mime-type cannot change but
-you can change the width, height, and parameters. The parameters are used to
-notify the plugin which sub-plugin to execute and which drawing model to use.
-
-<object type="application/x-testbrowserplugin" height=50 width=250>
- <param name="DrawingModel" value="Surface" />
- <param name="PluginType" value="Background" />
-</object>
-
-
-##############################
-## (D) SUB-PLUGINS ###########
-
-Each sub-plugin corresponds to exactly one plugin type and can support one or
-more drawing models. In the subsections below there are descriptions of each of
-the sub-plugins as well as the information required to create the html snippets.
-
-#######################
-## (D1) ANIMATION #####
-
-PLUGIN TYPE: Animation
-DRAWING MODEL: Bitmap
-
-This plugin draws a ball bouncing around the screen. If the plugin is not entirely
-on the screen and it it touched, then it will attempt to center itself on screen.
-
-#######################
-## (D2) AUDIO #########
-
-PLUGIN TYPE: Audio
-DRAWING MODEL: Bitmap
-
-This plugin plays a raw audio file located at /sdcard/sample.raw (need to supply
-your own). It uses touch to trigger the play, pause, and stop buttons.
-
-#######################
-## (D3) BACKGROUND ####
-
-PLUGIN TYPE: Background
-DRAWING MODEL: Surface
-
-This plugin has minimal visual components but mainly runs API tests in the
-background. The plugin handles scaling its own bitmap on zoom which in this
-case is a simple string of text. The output of this plugin is found in the logs
-as it prints errors if it detects any API failures. Some of the API's tested are
-timers, javascript access, and bitmap formatting.
-
-#######################
-## (D4) FORM ##########
-
-PLUGIN TYPE: Form
-DRAWING MODEL: Bitmap
-
-This plugin mimics a simple username/password form. You can select a textbox by
-either touching it or using the navigation keys. Once selected the box will
-highlight and the keyboard will appear. If the textbox selected is not fully
-in view then the plugin will ensure it is centered on the screen.
-
-#######################
-## (D5) PAINT #########
-
-PLUGIN TYPE: Paint
-DRAWING MODEL: Surface
-
-This plugin provides a surface that the user can "paint" on. The inputs method
-can be toggled between mouse (dots) and touch (lines). This plugin has a fixed
-surface and allows the browser to scale the surface when zooming.
diff --git a/samples/BrowserPlugin/jni/Android.mk b/samples/BrowserPlugin/jni/Android.mk
deleted file mode 100644
index d444bb0..0000000
--- a/samples/BrowserPlugin/jni/Android.mk
+++ /dev/null
@@ -1,68 +0,0 @@
-##
-##
-## Copyright 2008, The Android Open Source Project
-##
-## Redistribution and use in source and binary forms, with or without
-## modification, are permitted provided that the following conditions
-## are met:
-## * Redistributions of source code must retain the above copyright
-## notice, this list of conditions and the following disclaimer.
-## * Redistributions in binary form must reproduce the above copyright
-## notice, this list of conditions and the following disclaimer in the
-## documentation and/or other materials provided with the distribution.
-##
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
-## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
-## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-##
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- main.cpp \
- PluginObject.cpp \
- animation/AnimationPlugin.cpp \
- audio/AudioPlugin.cpp \
- background/BackgroundPlugin.cpp \
- form/FormPlugin.cpp \
- navigation/NavigationPlugin.cpp \
- paint/PaintPlugin.cpp \
- video/VideoPlugin.cpp \
- jni-bridge.cpp \
-
-LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE) \
- $(LOCAL_PATH) \
- $(LOCAL_PATH)/animation \
- $(LOCAL_PATH)/audio \
- $(LOCAL_PATH)/background \
- $(LOCAL_PATH)/form \
- $(LOCAL_PATH)/navigation \
- $(LOCAL_PATH)/paint \
- $(LOCAL_PATH)/video \
- external/webkit/WebCore/bridge \
- external/webkit/WebCore/plugins \
- external/webkit/WebCore/platform/android/JavaVM \
- external/webkit/WebKit/android/plugins
-
-LOCAL_SHARED_LIBRARIES := \
- libnativehelper
-
-LOCAL_CFLAGS += -fvisibility=hidden
-LOCAL_PRELINK_MODULE:=false
-
-LOCAL_MODULE:= libsampleplugin
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp
deleted file mode 100644
index dd0fbac..0000000
--- a/samples/BrowserPlugin/jni/PluginObject.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
- consideration of your agreement to the following terms, and your use, installation,
- modification or redistribution of this Apple software constitutes acceptance of these
- terms. If you do not agree with these terms, please do not use, install, modify or
- redistribute this Apple software.
-
- In consideration of your agreement to abide by the following terms, and subject to these
- terms, Apple grants you a personal, non-exclusive license, under AppleÕs copyrights in
- this original Apple software (the "Apple Software"), to use, reproduce, modify and
- redistribute the Apple Software, with or without modifications, in source and/or binary
- forms; provided that if you redistribute the Apple Software in its entirety and without
- modifications, you must retain this notice and the following text and disclaimers in all
- such redistributions of the Apple Software. Neither the name, trademarks, service marks
- or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
- the Apple Software without specific prior written permission from Apple. Except as expressly
- stated in this notice, no other rights or licenses, express or implied, are granted by Apple
- herein, including but not limited to any patent rights that may be infringed by your
- derivative works or by other works in which the Apple Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
- EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
- USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
- REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
- WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
- OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include "main.h"
-#include "PluginObject.h"
-
-int SubPlugin::getPluginWidth() {
- PluginObject *obj = (PluginObject*) inst()->pdata;
- return obj->window->width;
-}
-
-int SubPlugin::getPluginHeight() {
- PluginObject *obj = (PluginObject*) inst()->pdata;
- return obj->window->height;
-}
-
-bool SurfaceSubPlugin::supportsDrawingModel(ANPDrawingModel model) {
- return (model == kSurface_ANPDrawingModel);
-}
-
-void SurfaceSubPlugin::setContext(jobject context) {
- JNIEnv* env = NULL;
- if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
-
- // if one exists then free its global reference
- if (m_context) {
- env->DeleteGlobalRef(m_context);
- m_context = NULL;
- }
-
- // create a new global ref
- if (context) {
- context = env->NewGlobalRef(context);
- }
-
- // set the value
- m_context = context;
- }
-}
-
-static void pluginInvalidate(NPObject *obj);
-static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
-static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
-static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
-static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
-static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
-static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
-static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
-static void pluginDeallocate(NPObject *obj);
-static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name);
-static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
-
-
-
-static NPClass pluginClass = {
- NP_CLASS_STRUCT_VERSION,
- pluginAllocate,
- pluginDeallocate,
- pluginInvalidate,
- pluginHasMethod,
- pluginInvoke,
- pluginInvokeDefault,
- pluginHasProperty,
- pluginGetProperty,
- pluginSetProperty,
- pluginRemoveProperty,
- pluginEnumerate
-};
-
-NPClass *getPluginClass(void)
-{
- return &pluginClass;
-}
-
-static bool identifiersInitialized = false;
-
-#define ID_TESTFILE_PROPERTY 0
-#define NUM_PROPERTY_IDENTIFIERS 1
-
-static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
-static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
- "testfile"
-};
-
-#define ID_GETTESTFILE_METHOD 0
-#define NUM_METHOD_IDENTIFIERS 1
-
-static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
-static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
- "getTestFile"
-};
-
-static void initializeIdentifiers(void)
-{
- browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
- browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
-}
-
-static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
-{
- int i;
- for (i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
- if (name == pluginPropertyIdentifiers[i])
- return true;
- return false;
-}
-
-static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
-{
- int i;
- for (i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
- if (name == pluginMethodIdentifiers[i])
- return true;
- return false;
-}
-
-static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
-{
- PluginObject *plugin = (PluginObject *)obj;
- if (name == pluginPropertyIdentifiers[ID_TESTFILE_PROPERTY]) {
- BOOLEAN_TO_NPVARIANT(true, *variant);
- return true;
- }
- return false;
-}
-
-static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
-{
- return false;
-}
-
-static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
-{
- PluginObject *plugin = (PluginObject *)obj;
- if (name == pluginMethodIdentifiers[ID_GETTESTFILE_METHOD]) {
- return true;
- }
- return false;
-}
-
-static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
-{
- return false;
-}
-
-static void pluginInvalidate(NPObject *obj)
-{
- // Release any remaining references to JavaScript objects.
-}
-
-static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
-{
- PluginObject *newInstance = (PluginObject*) malloc(sizeof(PluginObject));
- newInstance->header._class = theClass;
- newInstance->header.referenceCount = 1;
-
- if (!identifiersInitialized) {
- identifiersInitialized = true;
- initializeIdentifiers();
- }
-
- newInstance->npp = npp;
-
- return &newInstance->header;
-}
-
-static void pluginDeallocate(NPObject *obj)
-{
- free(obj);
-}
-
-static bool pluginRemoveProperty(NPObject *npobj, NPIdentifier name)
-{
- return false;
-}
-
-static bool pluginEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
-{
- return false;
-}
diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h
deleted file mode 100644
index 0ebed28..0000000
--- a/samples/BrowserPlugin/jni/PluginObject.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
- consideration of your agreement to the following terms, and your use, installation,
- modification or redistribution of this Apple software constitutes acceptance of these
- terms. If you do not agree with these terms, please do not use, install, modify or
- redistribute this Apple software.
-
- In consideration of your agreement to abide by the following terms, and subject to these
- terms, Apple grants you a personal, non-exclusive license, under Apple�s copyrights in
- this original Apple software (the "Apple Software"), to use, reproduce, modify and
- redistribute the Apple Software, with or without modifications, in source and/or binary
- forms; provided that if you redistribute the Apple Software in its entirety and without
- modifications, you must retain this notice and the following text and disclaimers in all
- such redistributions of the Apple Software. Neither the name, trademarks, service marks
- or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
- the Apple Software without specific prior written permission from Apple. Except as expressly
- stated in this notice, no other rights or licenses, express or implied, are granted by Apple
- herein, including but not limited to any patent rights that may be infringed by your
- derivative works or by other works in which the Apple Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
- EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
- USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
- REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
- WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
- OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PluginObject__DEFINED
-#define PluginObject__DEFINED
-
-#include "main.h"
-#include <jni.h>
-
-enum CustomEventTypes {
- kSurfaceCreated_CustomEvent = 0,
- kSurfaceChanged_CustomEvent = 1,
- kSurfaceDestroyed_CustomEvent = 2,
-};
-typedef int32_t CustomEventType;
-
-class SubPlugin {
-public:
- SubPlugin(NPP inst) : m_inst(inst) {}
- virtual ~SubPlugin() {}
- virtual int16 handleEvent(const ANPEvent* evt) = 0;
- virtual bool supportsDrawingModel(ANPDrawingModel) = 0;
-
- int getPluginWidth();
- int getPluginHeight();
-
- NPP inst() const { return m_inst; }
-
-private:
- NPP m_inst;
-};
-
-class SurfaceSubPlugin : public SubPlugin {
-public:
- SurfaceSubPlugin(NPP inst) : SubPlugin(inst) { m_context = NULL; }
- virtual ~SurfaceSubPlugin() {}
- virtual jobject getSurface() = 0;
- virtual bool supportsDrawingModel(ANPDrawingModel);
-
- void setContext(jobject context);
-
- jobject m_context;
-};
-
-enum PluginTypes {
- kAnimation_PluginType = 1,
- kAudio_PluginType = 2,
- kBackground_PluginType = 3,
- kForm_PluginType = 4,
- kText_PluginType = 5,
- kPaint_PluginType = 6,
- kVideo_PluginType = 7,
- kNavigation_PluginType = 8,
-};
-typedef uint32_t PluginType;
-
-typedef struct PluginObject {
- NPObject header;
- NPP npp;
- NPWindow* window;
-
- PluginType pluginType;
- SubPlugin* activePlugin;
-
-} PluginObject;
-
-NPClass *getPluginClass(void);
-
-#endif // PluginObject__DEFINED
diff --git a/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp b/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
deleted file mode 100644
index 72a11c9..0000000
--- a/samples/BrowserPlugin/jni/animation/AnimationPlugin.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "AnimationPlugin.h"
-
-#include <math.h>
-#include <string.h>
-
-extern NPNetscapeFuncs* browser;
-extern ANPLogInterfaceV0 gLogI;
-extern ANPCanvasInterfaceV0 gCanvasI;
-extern ANPPaintInterfaceV0 gPaintI;
-extern ANPPathInterfaceV0 gPathI;
-extern ANPWindowInterfaceV0 gWindowI;
-
-static uint16 rnd16(float x, int inset) {
- int ix = (int)roundf(x) + inset;
- if (ix < 0) {
- ix = 0;
- }
- return static_cast<uint16>(ix);
-}
-
-static void inval(NPP instance, const ANPRectF& r, bool doAA) {
- const int inset = doAA ? -1 : 0;
-
- NPRect inval;
- inval.left = rnd16(r.left, inset);
- inval.top = rnd16(r.top, inset);
- inval.right = rnd16(r.right, -inset);
- inval.bottom = rnd16(r.bottom, -inset);
- browser->invalidaterect(instance, &inval);
-}
-
-static void bounce(float* x, float* dx, const float max) {
- *x += *dx;
- if (*x < 0) {
- *x = 0;
- if (*dx < 0) {
- *dx = -*dx;
- }
- } else if (*x > max) {
- *x = max;
- if (*dx > 0) {
- *dx = -*dx;
- }
- }
-}
-///////////////////////////////////////////////////////////////////////////////
-
-BallAnimation::BallAnimation(NPP inst) : SubPlugin(inst) {
- m_x = m_y = 0;
- m_dx = 7 * SCALE;
- m_dy = 5 * SCALE;
-
- memset(&m_oval, 0, sizeof(m_oval));
-
- m_paint = gPaintI.newPaint();
- gPaintI.setFlags(m_paint, gPaintI.getFlags(m_paint) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paint, 0xFFFF0000);
-
- //register for touch events
- ANPEventFlags flags = kTouch_ANPEventFlag;
- NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error selecting input events.");
- }
-}
-
-BallAnimation::~BallAnimation() {
- gPaintI.deletePaint(m_paint);
-}
-
-bool BallAnimation::supportsDrawingModel(ANPDrawingModel model) {
- return (model == kBitmap_ANPDrawingModel);
-}
-
-void BallAnimation::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
-
- // create a canvas
- ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
-
- // clip the canvas
- ANPRectF clipR;
- clipR.left = clip.left;
- clipR.top = clip.top;
- clipR.right = clip.right;
- clipR.bottom = clip.bottom;
- gCanvasI.clipRect(canvas, &clipR);
-
- // setup variables
- PluginObject *obj = (PluginObject*) inst()->pdata;
- const float OW = 20;
- const float OH = 20;
- const int W = obj->window->width;
- const int H = obj->window->height;
-
- // paint the canvas (using the path API)
- gCanvasI.drawColor(canvas, 0xFFFFFFFF);
- {
- ANPPath* path = gPathI.newPath();
-
- float cx = W * 0.5f;
- float cy = H * 0.5f;
- gPathI.moveTo(path, 0, 0);
- gPathI.quadTo(path, cx, cy, W, 0);
- gPathI.quadTo(path, cx, cy, W, H);
- gPathI.quadTo(path, cx, cy, 0, H);
- gPathI.quadTo(path, cx, cy, 0, 0);
-
- gPaintI.setColor(m_paint, 0xFF0000FF);
- gCanvasI.drawPath(canvas, path, m_paint);
-
- ANPRectF bounds;
- memset(&bounds, 0, sizeof(bounds));
- gPathI.getBounds(path, &bounds);
- gPathI.deletePath(path);
- }
-
- // draw the oval
- inval(inst(), m_oval, true); // inval the old
- m_oval.left = m_x;
- m_oval.top = m_y;
- m_oval.right = m_x + OW;
- m_oval.bottom = m_y + OH;
- inval(inst(), m_oval, true); // inval the new
- gPaintI.setColor(m_paint, 0xFFFF0000);
- gCanvasI.drawOval(canvas, &m_oval, m_paint);
-
- // update the coordinates of the oval
- bounce(&m_x, &m_dx, obj->window->width - OW);
- bounce(&m_y, &m_dy, obj->window->height - OH);
-
- // delete the canvas
- gCanvasI.deleteCanvas(canvas);
-}
-
-void BallAnimation::showEntirePluginOnScreen() {
- NPP instance = this->inst();
- PluginObject *obj = (PluginObject*) instance->pdata;
- NPWindow *window = obj->window;
-
- ANPRectI visibleRects[1];
-
- visibleRects[0].left = 0;
- visibleRects[0].top = 0;
- visibleRects[0].right = window->width;
- visibleRects[0].bottom = window->height;
-
- gWindowI.setVisibleRects(instance, visibleRects, 1);
- gWindowI.clearVisibleRects(instance);
-}
-
-int16 BallAnimation::handleEvent(const ANPEvent* evt) {
- NPP instance = this->inst();
-
- switch (evt->eventType) {
- case kDraw_ANPEventType:
- switch (evt->data.draw.model) {
- case kBitmap_ANPDrawingModel:
- drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
- return 1;
- default:
- break; // unknown drawing model
- }
- case kTouch_ANPEventType:
- if (kDown_ANPTouchAction == evt->data.touch.action) {
- showEntirePluginOnScreen();
- }
- return 1;
- default:
- break;
- }
- return 0; // unknown or unhandled event
-}
diff --git a/samples/BrowserPlugin/jni/animation/AnimationPlugin.h b/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
deleted file mode 100644
index ef2a3f54..0000000
--- a/samples/BrowserPlugin/jni/animation/AnimationPlugin.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PluginObject.h"
-
-#ifndef pluginGraphics__DEFINED
-#define pluginGraphics__DEFINED
-
-class BallAnimation : public SubPlugin {
-public:
- BallAnimation(NPP inst);
- virtual ~BallAnimation();
- virtual bool supportsDrawingModel(ANPDrawingModel);
- virtual int16 handleEvent(const ANPEvent* evt);
-private:
- void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
- void showEntirePluginOnScreen();
-
- float m_x;
- float m_y;
- float m_dx;
- float m_dy;
-
- ANPRectF m_oval;
- ANPPaint* m_paint;
-
- static const float SCALE = 0.1;
-};
-
-#endif // pluginGraphics__DEFINED
diff --git a/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp b/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp
deleted file mode 100644
index 9731f19..0000000
--- a/samples/BrowserPlugin/jni/audio/AudioPlugin.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "AudioPlugin.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <time.h>
-#include <math.h>
-#include <string.h>
-
-extern NPNetscapeFuncs* browser;
-extern ANPLogInterfaceV0 gLogI;
-extern ANPCanvasInterfaceV0 gCanvasI;
-extern ANPPaintInterfaceV0 gPaintI;
-extern ANPAudioTrackInterfaceV0 gSoundI;
-extern ANPTypefaceInterfaceV0 gTypefaceI;
-
-
-static void inval(NPP instance) {
- browser->invalidaterect(instance, NULL);
-}
-
-static uint16 rnd16(float x, int inset) {
- int ix = (int)roundf(x) + inset;
- if (ix < 0) {
- ix = 0;
- }
- return static_cast<uint16>(ix);
-}
-
-static void inval(NPP instance, const ANPRectF& r, bool doAA) {
- const int inset = doAA ? -1 : 0;
-
- PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
- NPRect inval;
- inval.left = rnd16(r.left, inset);
- inval.top = rnd16(r.top, inset);
- inval.right = rnd16(r.right, -inset);
- inval.bottom = rnd16(r.bottom, -inset);
- browser->invalidaterect(instance, &inval);
-}
-
-static void audioCallback(ANPAudioEvent evt, void* user, ANPAudioBuffer* buffer) {
- switch (evt) {
- case kMoreData_ANPAudioEvent: {
- SoundPlay* play = reinterpret_cast<SoundPlay*>(user);
- size_t amount = fread(buffer->bufferData, 1, buffer->size, play->file);
- buffer->size = amount;
- if (amount == 0) {
- gSoundI.stop(play->track);
- fclose(play->file);
- play->file = NULL;
- // TODO need to notify our main thread to delete the track now
- }
-
- if (play->fileSize > 0) {
- // TODO we need to properly update the progress value
- play->progress = 1;
- inval(play->instance);
- }
-
-
- break;
- }
- default:
- break;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-AudioPlugin::AudioPlugin(NPP inst) : SubPlugin(inst) {
-
- const char path[] = "/sdcard/sample.raw";
-
- // open a file stream
- FILE* f = fopen(path, "r");
- gLogI.log(kDebug_ANPLogType, "--- path %s FILE %p", path, f);
-
- // setup our private audio struct's default values
- m_soundPlay = new SoundPlay;
- m_soundPlay->instance = inst;
- m_soundPlay->progress = 0;
- m_soundPlay->fileSize = 0;
- m_soundPlay->file = f;
- m_soundPlay->track = NULL;
-
- // create the audio track
- if (f) {
- m_soundPlay->track = gSoundI.newTrack(44100, kPCM16Bit_ANPSampleFormat, 2, audioCallback, m_soundPlay);
- if (!m_soundPlay->track) {
- fclose(f);
- m_soundPlay->file = NULL;
- }
- }
-
- // get the audio file's size
- int fileDescriptor = open(path, O_RDONLY);
- struct stat fileStatus;
-
- if(fileDescriptor <= 0) {
- gLogI.log(kError_ANPLogType, "fopen error");
- }
- else if (fstat(fileDescriptor, &fileStatus) != 0) {
- gLogI.log(kDebug_ANPLogType, "File Size: %d", fileStatus.st_size);
- m_soundPlay->fileSize = fileStatus.st_size;
- } else {
- gLogI.log(kError_ANPLogType, "fstat error");
- }
-
- // configure the UI elements
- m_activeTouch = false;
-
- memset(&m_trackRect, 0, sizeof(m_trackRect));
- memset(&m_playRect, 0, sizeof(m_playRect));
- memset(&m_pauseRect, 0, sizeof(m_pauseRect));
- memset(&m_stopRect, 0, sizeof(m_stopRect));
-
- m_paintTrack = gPaintI.newPaint();
- gPaintI.setFlags(m_paintTrack, gPaintI.getFlags(m_paintTrack) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintTrack, 0xFFC0C0C0);
-
- m_paintRect = gPaintI.newPaint();
- gPaintI.setFlags(m_paintRect, gPaintI.getFlags(m_paintRect) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintRect, 0xFFA8A8A8);
-
- m_paintText = gPaintI.newPaint();
- gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintText, 0xFF2F4F4F);
- gPaintI.setTextSize(m_paintText, 18);
-
- m_paintTrackProgress = gPaintI.newPaint();
- gPaintI.setFlags(m_paintTrackProgress, gPaintI.getFlags(m_paintTrackProgress) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintTrackProgress, 0xFF545454);
-
- m_paintActiveRect = gPaintI.newPaint();
- gPaintI.setFlags(m_paintActiveRect, gPaintI.getFlags(m_paintActiveRect) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintActiveRect, 0xFF545454);
-
- ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
- gPaintI.setTypeface(m_paintText, tf);
- gTypefaceI.unref(tf);
-
- //register for touch events
- ANPEventFlags flags = kTouch_ANPEventFlag;
- NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error selecting input events.");
- }
-}
-
-AudioPlugin::~AudioPlugin() {
- gPaintI.deletePaint(m_paintTrack);
- gPaintI.deletePaint(m_paintRect);
- gPaintI.deletePaint(m_paintText);
- gPaintI.deletePaint(m_paintTrackProgress);
- gPaintI.deletePaint(m_paintActiveRect);
- if(m_soundPlay->track)
- gSoundI.deleteTrack(m_soundPlay->track);
- delete m_soundPlay;
-}
-
-bool AudioPlugin::supportsDrawingModel(ANPDrawingModel model) {
- return (model == kBitmap_ANPDrawingModel);
-}
-
-void AudioPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
- ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
-
- ANPRectF clipR;
- clipR.left = clip.left;
- clipR.top = clip.top;
- clipR.right = clip.right;
- clipR.bottom = clip.bottom;
- gCanvasI.clipRect(canvas, &clipR);
-
- draw(canvas);
- gCanvasI.deleteCanvas(canvas);
-}
-
-void AudioPlugin::draw(ANPCanvas* canvas) {
-
- PluginObject *obj = (PluginObject*) this->inst()->pdata;
-
- gLogI.log(kError_ANPLogType, "Drawing");
-
- const float trackHeight = 30;
- const float buttonWidth = 60;
- const float buttonHeight = 30;
- const int W = obj->window->width;
- const int H = obj->window->height;
-
- // color the plugin canvas
- gCanvasI.drawColor(canvas, 0xFFCDCDCD);
-
- // get font metrics
- ANPFontMetrics fontMetrics;
- gPaintI.getFontMetrics(m_paintText, &fontMetrics);
-
- // draw the track box (1 px from the edge)
- m_trackRect.left = 1;
- m_trackRect.top = 1;
- m_trackRect.right = W - 2;
- m_trackRect.bottom = 1 + trackHeight;
- gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrack);
-
- // draw the progress bar
- if (m_soundPlay->progress > 0) {
- // TODO need to draw progress bar to cover the proper percentage of the track bar
- gCanvasI.drawRect(canvas, &m_trackRect, m_paintTrackProgress);
- }
-
- // draw the play box (under track box)
- m_playRect.left = m_trackRect.left + 5;
- m_playRect.top = m_trackRect.bottom + 10;
- m_playRect.right = m_playRect.left + buttonWidth;
- m_playRect.bottom = m_playRect.top + buttonHeight;
- gCanvasI.drawRect(canvas, &m_playRect, getPaint(&m_playRect));
- // draw the play box (under track box)
- const char playText[] = "Play";
- gCanvasI.drawText(canvas, playText, sizeof(playText)-1, m_playRect.left + 5,
- m_playRect.top - fontMetrics.fTop, m_paintText);
-
- // draw the pause box (under track box)
- m_pauseRect.left = m_playRect.right + 20;
- m_pauseRect.top = m_trackRect.bottom + 10;
- m_pauseRect.right = m_pauseRect.left + buttonWidth;
- m_pauseRect.bottom = m_pauseRect.top + buttonHeight;
- gCanvasI.drawRect(canvas, &m_pauseRect, getPaint(&m_pauseRect));
- // draw the text in the pause box
- const char pauseText[] = "Pause";
- gCanvasI.drawText(canvas, pauseText, sizeof(pauseText)-1, m_pauseRect.left + 5,
- m_pauseRect.top - fontMetrics.fTop, m_paintText);
-
- // draw the stop box (under track box)
- m_stopRect.left = m_pauseRect.right + 20;
- m_stopRect.top = m_trackRect.bottom + 10;
- m_stopRect.right = m_stopRect.left + buttonWidth;
- m_stopRect.bottom = m_stopRect.top + buttonHeight;
- gCanvasI.drawRect(canvas, &m_stopRect, getPaint(&m_stopRect));
- // draw the text in the pause box
- const char stopText[] = "Stop";
- gCanvasI.drawText(canvas, stopText, sizeof(stopText)-1, m_stopRect.left + 5,
- m_stopRect.top - fontMetrics.fTop, m_paintText);
-}
-
-ANPPaint* AudioPlugin::getPaint(ANPRectF* input) {
- return (input == m_activeRect) ? m_paintActiveRect : m_paintRect;
-}
-
-int16 AudioPlugin::handleEvent(const ANPEvent* evt) {
- NPP instance = this->inst();
-
- switch (evt->eventType) {
- case kDraw_ANPEventType:
- switch (evt->data.draw.model) {
- case kBitmap_ANPDrawingModel:
- drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
- return 1;
- default:
- break; // unknown drawing model
- }
-
- case kTouch_ANPEventType: {
- int x = evt->data.touch.x;
- int y = evt->data.touch.y;
- if (kDown_ANPTouchAction == evt->data.touch.action) {
-
- m_activeTouchRect = validTouch(x,y);
- if(m_activeTouchRect) {
- m_activeTouch = true;
- return 1;
- }
-
- } else if (kUp_ANPTouchAction == evt->data.touch.action && m_activeTouch) {
- handleTouch(x, y);
- m_activeTouch = false;
- return 1;
- } else if (kCancel_ANPTouchAction == evt->data.touch.action) {
- m_activeTouch = false;
- }
- break;
- }
- default:
- break;
- }
- return 0; // unknown or unhandled event
-}
-
-void AudioPlugin::invalActiveRect() {
-
-}
-
-ANPRectF* AudioPlugin::validTouch(int x, int y) {
-
- if (m_playRect.left && x < m_playRect.right && y > m_playRect.top && y < m_playRect.bottom)
- return &m_playRect;
- else if (m_pauseRect.left && x < m_pauseRect.right && y > m_pauseRect.top && y < m_pauseRect.bottom)
- return &m_pauseRect;
- else if (x > m_stopRect.left && x < m_stopRect.right && y > m_stopRect.top && y < m_stopRect.bottom)
- return &m_stopRect;
- else
- return NULL;
-}
-
-void AudioPlugin::handleTouch(int x, int y) {
- NPP instance = this->inst();
-
- // if the track is null then return
- if (NULL == m_soundPlay->track) {
- gLogI.log(kError_ANPLogType, "---- %p unable to create track",
- instance);
- return;
- }
-
- // check to make sure the currentRect matches the activeRect
- ANPRectF* currentRect = validTouch(x,y);
- if (m_activeTouchRect != currentRect)
- return;
-
- if (currentRect == &m_playRect) {
-
- gLogI.log(kDebug_ANPLogType, "---- %p starting track (%d)",
- m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
-
- if (gSoundI.isStopped(m_soundPlay->track)) {
- gSoundI.start(m_soundPlay->track);
- }
- }
- else if (currentRect == &m_pauseRect) {
-
- gLogI.log(kDebug_ANPLogType, "---- %p pausing track (%d)",
- m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
-
- if (!gSoundI.isStopped(m_soundPlay->track)) {
- gSoundI.pause(m_soundPlay->track);
- }
- }
- else if (currentRect == &m_stopRect) {
-
- gLogI.log(kDebug_ANPLogType, "---- %p stopping track (%d)",
- m_soundPlay->track, gSoundI.isStopped(m_soundPlay->track));
-
- if (!gSoundI.isStopped(m_soundPlay->track)) {
- gSoundI.stop(m_soundPlay->track);
- }
- if (m_soundPlay->file) {
- fseek(m_soundPlay->file, 0, SEEK_SET);
- }
- }
- else {
- return;
- }
-
- // set the currentRect to be the activeRect
- m_activeRect = currentRect;
- inval(instance);
-}
diff --git a/samples/BrowserPlugin/jni/audio/AudioPlugin.h b/samples/BrowserPlugin/jni/audio/AudioPlugin.h
deleted file mode 100644
index 129d33a..0000000
--- a/samples/BrowserPlugin/jni/audio/AudioPlugin.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PluginObject.h"
-#include <stdio.h>
-
-#ifndef audioPlugin__DEFINED
-#define audioPlugin__DEFINED
-
-struct SoundPlay {
- NPP instance;
- ANPAudioTrack* track;
- FILE* file;
- int fileSize;
- int progress; // value between 0 and 100
-};
-
-class AudioPlugin : public SubPlugin {
-public:
- AudioPlugin(NPP inst);
- virtual ~AudioPlugin();
- virtual bool supportsDrawingModel(ANPDrawingModel);
- virtual int16 handleEvent(const ANPEvent* evt);
-private:
- void draw(ANPCanvas*);
- void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
-
- void handleTouch(int x, int y);
- void invalActiveRect();
- ANPPaint* getPaint(ANPRectF*);
- ANPRectF* validTouch(int x, int y);
-
- ANPRectF m_trackRect;
- ANPRectF m_playRect;
- ANPRectF m_pauseRect;
- ANPRectF m_stopRect;
-
- ANPPaint* m_paintTrack;
- ANPPaint* m_paintRect;
- ANPPaint* m_paintText;
-
- ANPPaint* m_paintTrackProgress;
- ANPPaint* m_paintActiveRect;
-
- SoundPlay* m_soundPlay;
-
- bool m_activeTouch;
- ANPRectF* m_activeTouchRect;
- ANPRectF* m_activeRect;
-};
-
-#endif // audioPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
deleted file mode 100644
index f749639..0000000
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "BackgroundPlugin.h"
-#include "android_npapi.h"
-
-#include <stdio.h>
-#include <sys/time.h>
-#include <time.h>
-#include <math.h>
-#include <string.h>
-
-extern NPNetscapeFuncs* browser;
-extern ANPBitmapInterfaceV0 gBitmapI;
-extern ANPCanvasInterfaceV0 gCanvasI;
-extern ANPLogInterfaceV0 gLogI;
-extern ANPPaintInterfaceV0 gPaintI;
-extern ANPSurfaceInterfaceV0 gSurfaceI;
-extern ANPSystemInterfaceV0 gSystemI;
-extern ANPTypefaceInterfaceV0 gTypefaceI;
-extern ANPWindowInterfaceV0 gWindowI;
-
-#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
-
-static uint32_t getMSecs() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return (uint32_t) (tv.tv_sec * 1000 + tv.tv_usec / 1000 ); // microseconds to milliseconds
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-BackgroundPlugin::BackgroundPlugin(NPP inst) : SurfaceSubPlugin(inst) {
-
- // initialize the drawing surface
- m_surface = NULL;
-
- //initialize bitmap transparency variables
- mFinishedStageOne = false;
- mFinishedStageTwo = false;
- mFinishedStageThree = false;
-
- // test basic plugin functionality
- test_logging(); // android logging
- test_timers(); // plugin timers
- test_bitmaps(); // android bitmaps
- test_domAccess();
- test_javascript();
- test_loadJavaClass();
-
- //register for touch events
- ANPEventFlags flags = kTouch_ANPEventFlag;
- NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error selecting input events.");
- }
-}
-
-BackgroundPlugin::~BackgroundPlugin() {
- setContext(NULL);
- destroySurface();
-}
-
-jobject BackgroundPlugin::getSurface() {
-
- if (m_surface) {
- return m_surface;
- }
-
- // load the appropriate java class and instantiate it
- JNIEnv* env = NULL;
- if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
- return NULL;
- }
-
- const char* className = "com.android.sampleplugin.BackgroundSurface";
- jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
-
- if(!backgroundClass) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
- return NULL;
- }
-
- jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "(Landroid/content/Context;)V");
- jobject backgroundSurface = env->NewObject(backgroundClass, constructor, m_context);
-
- if(!backgroundSurface) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
- return NULL;
- }
-
- m_surface = env->NewGlobalRef(backgroundSurface);
- return m_surface;
-}
-
-void BackgroundPlugin::destroySurface() {
- JNIEnv* env = NULL;
- if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
- env->DeleteGlobalRef(m_surface);
- m_surface = NULL;
- }
-}
-
-void BackgroundPlugin::drawPlugin(int surfaceWidth, int surfaceHeight) {
-
- // get the plugin's dimensions according to the DOM
- PluginObject *obj = (PluginObject*) inst()->pdata;
- const int W = obj->window->width;
- const int H = obj->window->height;
-
- // compute the current zoom level
- const float zoomFactorW = static_cast<float>(surfaceWidth) / W;
- const float zoomFactorH = static_cast<float>(surfaceHeight) / H;
-
- // check to make sure the zoom level is uniform
- if (zoomFactorW + .01 < zoomFactorH && zoomFactorW - .01 > zoomFactorH)
- gLogI.log(kError_ANPLogType, " ------ %p zoom is out of sync (%f,%f)",
- inst(), zoomFactorW, zoomFactorH);
-
- // scale the variables based on the zoom level
- const int fontSize = (int)(zoomFactorW * 16);
- const int leftMargin = (int)(zoomFactorW * 10);
-
- // lock the surface
- ANPBitmap bitmap;
- JNIEnv* env = NULL;
- if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
- !gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
- gLogI.log(kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
- return;
- }
-
- // create a canvas
- ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
- gCanvasI.drawColor(canvas, 0xFFFFFFFF);
-
- ANPPaint* paint = gPaintI.newPaint();
- gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(paint, 0xFFFF0000);
- gPaintI.setTextSize(paint, fontSize);
-
- ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
- gPaintI.setTypeface(paint, tf);
- gTypefaceI.unref(tf);
-
- ANPFontMetrics fm;
- gPaintI.getFontMetrics(paint, &fm);
-
- gPaintI.setColor(paint, 0xFF0000FF);
- const char c[] = "This is a background plugin.";
- gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
-
- // clean up variables and unlock the surface
- gPaintI.deletePaint(paint);
- gCanvasI.deleteCanvas(canvas);
- gSurfaceI.unlock(env, m_surface);
-}
-
-int16 BackgroundPlugin::handleEvent(const ANPEvent* evt) {
- switch (evt->eventType) {
- case kDraw_ANPEventType:
- gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
- break;
- case kLifecycle_ANPEventType:
- switch (evt->data.lifecycle.action) {
- case kOnLoad_ANPLifecycleAction:
- gLogI.log(kDebug_ANPLogType, " ------ %p onLoad", inst());
- return 1;
- case kOnScreen_ANPLifecycleAction:
- gLogI.log(kDebug_ANPLogType, " ------ %p onScreen", inst());
- return 1;
- case kOffScreen_ANPLifecycleAction:
- gLogI.log(kDebug_ANPLogType, " ------ %p offScreen", inst());
- return 1;
- }
- break; // end kLifecycle_ANPEventType
- case kTouch_ANPEventType:
- if (kLongPress_ANPTouchAction == evt->data.touch.action) {
- browser->geturl(inst(), "javascript:alert('Detected long press event.')", 0);
- gWindowI.requestFullScreen(inst());
- }
- else if (kDoubleTap_ANPTouchAction == evt->data.touch.action)
- browser->geturl(inst(), "javascript:alert('Detected double tap event.')", 0);
- break;
- case kKey_ANPEventType:
- gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
- break;
- default:
- break;
- }
- return 0; // unknown or unhandled event
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// LOGGING TESTS
-///////////////////////////////////////////////////////////////////////////////
-
-
-void BackgroundPlugin::test_logging() {
- NPP instance = this->inst();
-
- //LOG_ERROR(instance, " ------ %p Testing Log Error", instance);
- gLogI.log(kError_ANPLogType, " ------ %p Testing Log Error", instance);
- gLogI.log(kWarning_ANPLogType, " ------ %p Testing Log Warning", instance);
- gLogI.log(kDebug_ANPLogType, " ------ %p Testing Log Debug", instance);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// TIMER TESTS
-///////////////////////////////////////////////////////////////////////////////
-
-#define TIMER_INTERVAL 50
-static void timer_oneshot(NPP instance, uint32 timerID);
-static void timer_repeat(NPP instance, uint32 timerID);
-static void timer_neverfires(NPP instance, uint32 timerID);
-static void timer_latency(NPP instance, uint32 timerID);
-
-void BackgroundPlugin::test_timers() {
- NPP instance = this->inst();
-
- //Setup the testing counters
- mTimerRepeatCount = 5;
- mTimerLatencyCount = 5;
-
- // test for bogus timerID
- browser->unscheduletimer(instance, 999999);
- // test one-shot
- browser->scheduletimer(instance, 100, false, timer_oneshot);
- // test repeat
- browser->scheduletimer(instance, 50, true, timer_repeat);
- // test timer latency
- browser->scheduletimer(instance, TIMER_INTERVAL, true, timer_latency);
- mStartTime = mPrevTime = getMSecs();
- // test unschedule immediately
- uint32 id = browser->scheduletimer(instance, 100, false, timer_neverfires);
- browser->unscheduletimer(instance, id);
- // test double unschedule (should be no-op)
- browser->unscheduletimer(instance, id);
-
-}
-
-static void timer_oneshot(NPP instance, uint32 timerID) {
- gLogI.log(kDebug_ANPLogType, "-------- oneshot timer\n");
-}
-
-static void timer_repeat(NPP instance, uint32 timerID) {
- BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
-
- gLogI.log(kDebug_ANPLogType, "-------- repeat timer %d\n",
- obj->mTimerRepeatCount);
- if (--obj->mTimerRepeatCount == 0) {
- browser->unscheduletimer(instance, timerID);
- }
-}
-
-static void timer_neverfires(NPP instance, uint32 timerID) {
- gLogI.log(kError_ANPLogType, "-------- timer_neverfires!!!\n");
-}
-
-static void timer_latency(NPP instance, uint32 timerID) {
- BackgroundPlugin *obj = ((BackgroundPlugin*) ((PluginObject*) instance->pdata)->activePlugin);
-
- obj->mTimerLatencyCurrentCount += 1;
-
- uint32_t now = getMSecs();
- uint32_t interval = now - obj->mPrevTime;
- uint32_t dur = now - obj->mStartTime;
- uint32_t expectedDur = obj->mTimerLatencyCurrentCount * TIMER_INTERVAL;
- int32_t drift = dur - expectedDur;
- int32_t avgDrift = drift / obj->mTimerLatencyCurrentCount;
-
- obj->mPrevTime = now;
-
- gLogI.log(kDebug_ANPLogType,
- "-------- latency test: [%3d] interval %d expected %d, total %d expected %d, drift %d avg %d\n",
- obj->mTimerLatencyCurrentCount, interval, TIMER_INTERVAL, dur,
- expectedDur, drift, avgDrift);
-
- if (--obj->mTimerLatencyCount == 0) {
- browser->unscheduletimer(instance, timerID);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// BITMAP TESTS
-///////////////////////////////////////////////////////////////////////////////
-
-static void test_formats(NPP instance);
-
-void BackgroundPlugin::test_bitmaps() {
- test_formats(this->inst());
-}
-
-static void test_formats(NPP instance) {
-
- // TODO pull names from enum in npapi instead of hardcoding them
- static const struct {
- ANPBitmapFormat fFormat;
- const char* fName;
- } gRecs[] = {
- { kUnknown_ANPBitmapFormat, "unknown" },
- { kRGBA_8888_ANPBitmapFormat, "8888" },
- { kRGB_565_ANPBitmapFormat, "565" },
- };
-
- ANPPixelPacking packing;
- for (size_t i = 0; i < ARRAY_COUNT(gRecs); i++) {
- if (gBitmapI.getPixelPacking(gRecs[i].fFormat, &packing)) {
- gLogI.log(kDebug_ANPLogType,
- "pixel format [%d] %s has packing ARGB [%d %d] [%d %d] [%d %d] [%d %d]\n",
- gRecs[i].fFormat, gRecs[i].fName,
- packing.AShift, packing.ABits,
- packing.RShift, packing.RBits,
- packing.GShift, packing.GBits,
- packing.BShift, packing.BBits);
- } else {
- gLogI.log(kDebug_ANPLogType,
- "pixel format [%d] %s has no packing\n",
- gRecs[i].fFormat, gRecs[i].fName);
- }
- }
-}
-
-void BackgroundPlugin::test_bitmap_transparency(const ANPEvent* evt) {
- NPP instance = this->inst();
-
- // check default & set transparent
- if (!mFinishedStageOne) {
-
- gLogI.log(kDebug_ANPLogType, "BEGIN: testing bitmap transparency");
-
- //check to make sure it is not transparent
- if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
- gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
- }
-
- //make it transparent (any non-null value will set it to true)
- bool value = true;
- NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, &value);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error setting transparency.");
- }
-
- mFinishedStageOne = true;
- browser->invalidaterect(instance, NULL);
- }
- // check transparent & set opaque
- else if (!mFinishedStageTwo) {
-
- //check to make sure it is transparent
- if (evt->data.draw.data.bitmap.format != kRGBA_8888_ANPBitmapFormat) {
- gLogI.log(kError_ANPLogType, "bitmap did not change to transparent format");
- }
-
- //make it opaque
- NPError err = browser->setvalue(instance, NPPVpluginTransparentBool, NULL);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error setting transparency.");
- }
-
- mFinishedStageTwo = true;
- }
- // check opaque
- else if (!mFinishedStageThree) {
-
- //check to make sure it is not transparent
- if (evt->data.draw.data.bitmap.format == kRGBA_8888_ANPBitmapFormat) {
- gLogI.log(kError_ANPLogType, "bitmap default format is transparent");
- }
-
- gLogI.log(kDebug_ANPLogType, "END: testing bitmap transparency");
-
- mFinishedStageThree = true;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DOM TESTS
-///////////////////////////////////////////////////////////////////////////////
-
-void BackgroundPlugin::test_domAccess() {
- NPP instance = this->inst();
-
- gLogI.log(kDebug_ANPLogType, " ------ %p Testing DOM Access", instance);
-
- // Get the plugin's DOM object
- NPObject* windowObject = NULL;
- browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
-
- if (!windowObject)
- gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
-
- // Retrieve a property from the plugin's DOM object
- NPIdentifier topIdentifier = browser->getstringidentifier("top");
- NPVariant topObjectVariant;
- browser->getproperty(instance, windowObject, topIdentifier, &topObjectVariant);
-
- if (topObjectVariant.type != NPVariantType_Object)
- gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for DOM Property: %d,%d", instance, topObjectVariant.type, NPVariantType_Object);
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// JAVASCRIPT TESTS
-///////////////////////////////////////////////////////////////////////////////
-
-
-void BackgroundPlugin::test_javascript() {
- NPP instance = this->inst();
-
- gLogI.log(kDebug_ANPLogType, " ------ %p Testing JavaScript Access", instance);
-
- // Get the plugin's DOM object
- NPObject* windowObject = NULL;
- browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
-
- if (!windowObject)
- gLogI.log(kError_ANPLogType, " ------ %p Unable to retrieve DOM Window", instance);
-
- // create a string (JS code) that is stored in memory allocated by the browser
- const char* jsString = "1200 + 34";
- void* stringMem = browser->memalloc(strlen(jsString));
- memcpy(stringMem, jsString, strlen(jsString));
-
- // execute the javascript in the plugin's DOM object
- NPString script = { (char*)stringMem, strlen(jsString) };
- NPVariant scriptVariant;
- if (!browser->evaluate(instance, windowObject, &script, &scriptVariant))
- gLogI.log(kError_ANPLogType, " ------ %p Unable to eval the JS.", instance);
-
- if (scriptVariant.type == NPVariantType_Int32) {
- if (scriptVariant.value.intValue != 1234)
- gLogI.log(kError_ANPLogType, " ------ %p Invalid Value for JS Return: %d,1234", instance, scriptVariant.value.intValue);
- } else {
- gLogI.log(kError_ANPLogType, " ------ %p Invalid Variant type for JS Return: %d,%d", instance, scriptVariant.type, NPVariantType_Int32);
- }
-
- // free the memory allocated within the browser
- browser->memfree(stringMem);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Load Java Classes Tests
-///////////////////////////////////////////////////////////////////////////////
-
-void BackgroundPlugin::test_loadJavaClass() {
-
- JNIEnv* env = NULL;
- if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to get env");
- return;
- }
-
- const char* className = "com.android.sampleplugin.BackgroundTest";
- jclass backgroundClass = gSystemI.loadJavaClass(inst(), className);
-
- if(!backgroundClass) {
- gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to load class");
- return;
- }
-
- jmethodID constructor = env->GetMethodID(backgroundClass, "<init>", "()V");
- jmethodID addMethod = env->GetMethodID(backgroundClass, "addInt", "(II)I");
- jobject backgroundObject = env->NewObject(backgroundClass, constructor);
-
- if(!backgroundObject) {
- gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: failed to construct object");
- return;
- }
-
- jint result = env->CallIntMethod(backgroundObject, addMethod, 2, 2);
-
- if (result != 4) {
- gLogI.log(kError_ANPLogType, " ---- LoadJavaTest: invalid result (%d != 4)", result);
- }
-}
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
deleted file mode 100644
index ebd77d1..0000000
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PluginObject.h"
-
-#ifndef backgroundPlugin__DEFINED
-#define backgroundPlugin__DEFINED
-
-class BackgroundPlugin : public SurfaceSubPlugin {
-public:
- BackgroundPlugin(NPP inst);
- virtual ~BackgroundPlugin();
- virtual int16 handleEvent(const ANPEvent* evt);
- virtual jobject getSurface();
-
- // Timer Testing Variables
- uint32_t mStartTime;
- uint32_t mPrevTime;
- int mTimerRepeatCount;
- int mTimerLatencyCount;
- int mTimerLatencyCurrentCount;
-
- // Bitmap Transparency Variables
- bool mFinishedStageOne; // check default & set transparent
- bool mFinishedStageTwo; // check transparent & set opaque
- bool mFinishedStageThree; // check opaque
-
-private:
- void drawPlugin(int surfaceWidth, int surfaceHeight);
- void destroySurface();
-
- jobject m_surface;
-
- void test_logging();
- void test_timers();
- void test_bitmaps();
- void test_bitmap_transparency(const ANPEvent* evt);
- void test_domAccess();
- void test_javascript();
- void test_loadJavaClass();
-
-};
-
-#endif // backgroundPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.cpp b/samples/BrowserPlugin/jni/form/FormPlugin.cpp
deleted file mode 100644
index 5a536d9..0000000
--- a/samples/BrowserPlugin/jni/form/FormPlugin.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "FormPlugin.h"
-
-#include <stdio.h>
-#include <sys/time.h>
-#include <time.h>
-#include <math.h>
-#include <string.h>
-
-extern NPNetscapeFuncs* browser;
-extern ANPLogInterfaceV0 gLogI;
-extern ANPCanvasInterfaceV0 gCanvasI;
-extern ANPPaintInterfaceV0 gPaintI;
-extern ANPTypefaceInterfaceV0 gTypefaceI;
-extern ANPWindowInterfaceV0 gWindowI;
-
-
-static void inval(NPP instance) {
- browser->invalidaterect(instance, NULL);
-}
-
-static uint16 rnd16(float x, int inset) {
- int ix = (int)roundf(x) + inset;
- if (ix < 0) {
- ix = 0;
- }
- return static_cast<uint16>(ix);
-}
-
-static void inval(NPP instance, const ANPRectF& r, bool doAA) {
- const int inset = doAA ? -1 : 0;
-
- PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
- NPRect inval;
- inval.left = rnd16(r.left, inset);
- inval.top = rnd16(r.top, inset);
- inval.right = rnd16(r.right, -inset);
- inval.bottom = rnd16(r.bottom, -inset);
- browser->invalidaterect(instance, &inval);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-FormPlugin::FormPlugin(NPP inst) : SubPlugin(inst) {
-
- m_hasFocus = false;
- m_activeInput = NULL;
-
- memset(&m_usernameInput, 0, sizeof(m_usernameInput));
- memset(&m_passwordInput, 0, sizeof(m_passwordInput));
-
- m_usernameInput.text[0] = '\0';
- m_usernameInput.charPtr = 0;
-
- m_passwordInput.text[0] = '\0';
- m_passwordInput.charPtr = 0;
-
- m_paintInput = gPaintI.newPaint();
- gPaintI.setFlags(m_paintInput, gPaintI.getFlags(m_paintInput) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintInput, 0xFFFFFFFF);
-
- m_paintActive = gPaintI.newPaint();
- gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintActive, 0xFFFFFF00);
-
- m_paintText = gPaintI.newPaint();
- gPaintI.setFlags(m_paintText, gPaintI.getFlags(m_paintText) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintText, 0xFF000000);
- gPaintI.setTextSize(m_paintText, 18);
-
- ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
- gPaintI.setTypeface(m_paintText, tf);
- gTypefaceI.unref(tf);
-
- //register for key and visibleRect events
- ANPEventFlags flags = kKey_ANPEventFlag;
- NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error selecting input events.");
- }
-}
-
-FormPlugin::~FormPlugin() {
- gPaintI.deletePaint(m_paintInput);
- gPaintI.deletePaint(m_paintActive);
- gPaintI.deletePaint(m_paintText);
-}
-
-bool FormPlugin::supportsDrawingModel(ANPDrawingModel model) {
- return (model == kBitmap_ANPDrawingModel);
-}
-
-void FormPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
- ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
-
- ANPRectF clipR;
- clipR.left = clip.left;
- clipR.top = clip.top;
- clipR.right = clip.right;
- clipR.bottom = clip.bottom;
- gCanvasI.clipRect(canvas, &clipR);
-
- draw(canvas);
- gCanvasI.deleteCanvas(canvas);
-}
-
-void FormPlugin::draw(ANPCanvas* canvas) {
- NPP instance = this->inst();
- PluginObject *obj = (PluginObject*) instance->pdata;
-
- const float inputWidth = 60;
- const float inputHeight = 30;
- const int W = obj->window->width;
- const int H = obj->window->height;
-
- // color the plugin canvas
- gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
-
- // draw the username box (5 px from the top edge)
- m_usernameInput.rect.left = 5;
- m_usernameInput.rect.top = 5;
- m_usernameInput.rect.right = W - 5;
- m_usernameInput.rect.bottom = m_usernameInput.rect.top + inputHeight;
- gCanvasI.drawRect(canvas, &m_usernameInput.rect, getPaint(&m_usernameInput));
- drawText(canvas, m_usernameInput);
-
- // draw the password box (5 px from the bottom edge)
- m_passwordInput.rect.left = 5;
- m_passwordInput.rect.top = H - (inputHeight + 5);
- m_passwordInput.rect.right = W - 5;
- m_passwordInput.rect.bottom = m_passwordInput.rect.top + inputHeight;
- gCanvasI.drawRect(canvas, &m_passwordInput.rect, getPaint(&m_passwordInput));
- drawPassword(canvas, m_passwordInput);
-
- //invalidate the canvas
- //inval(instance);
-}
-
-ANPPaint* FormPlugin::getPaint(TextInput* input) {
- return (input == m_activeInput) ? m_paintActive : m_paintInput;
-}
-
-void FormPlugin::drawText(ANPCanvas* canvas, TextInput textInput) {
-
- // get font metrics
- ANPFontMetrics fontMetrics;
- gPaintI.getFontMetrics(m_paintText, &fontMetrics);
-
- gCanvasI.drawText(canvas, textInput.text, textInput.charPtr,
- textInput.rect.left + 5,
- textInput.rect.bottom - fontMetrics.fBottom, m_paintText);
-}
-
-void FormPlugin::drawPassword(ANPCanvas* canvas, TextInput passwordInput) {
-
- // get font metrics
- ANPFontMetrics fontMetrics;
- gPaintI.getFontMetrics(m_paintText, &fontMetrics);
-
- // comput the circle dimensions and initial location
- float initialX = passwordInput.rect.left + 5;
- float ovalBottom = passwordInput.rect.bottom - 2;
- float ovalTop = ovalBottom - (fontMetrics.fBottom - fontMetrics.fTop);
- float ovalWidth = ovalBottom - ovalTop;
- float ovalSpacing = 3;
-
- // draw circles instead of the actual text
- for (uint32_t x = 0; x < passwordInput.charPtr; x++) {
- ANPRectF oval;
- oval.left = initialX + ((ovalWidth + ovalSpacing) * (float) x);
- oval.right = oval.left + ovalWidth;
- oval.top = ovalTop;
- oval.bottom = ovalBottom;
- gCanvasI.drawOval(canvas, &oval, m_paintText);
- }
-}
-
-int16 FormPlugin::handleEvent(const ANPEvent* evt) {
- NPP instance = this->inst();
-
- switch (evt->eventType) {
- case kDraw_ANPEventType:
- switch (evt->data.draw.model) {
- case kBitmap_ANPDrawingModel:
- drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
- return 1;
- default:
- break; // unknown drawing model
- }
- break;
-
- case kLifecycle_ANPEventType:
- if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
- gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
-
- if (m_activeInput) {
- // hide the keyboard
- gWindowI.showKeyboard(instance, false);
-
- //reset the activeInput
- m_activeInput = NULL;
- }
-
- m_hasFocus = false;
- inval(instance);
- return 1;
- }
- else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
- gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
- m_hasFocus = true;
- inval(instance);
- return 1;
- }
- break;
-
- case kMouse_ANPEventType: {
-
- int x = evt->data.mouse.x;
- int y = evt->data.mouse.y;
- if (kDown_ANPMouseAction == evt->data.mouse.action) {
-
- TextInput* currentInput = validTap(x,y);
-
- if (currentInput)
- gWindowI.showKeyboard(instance, true);
- else if (m_activeInput)
- gWindowI.showKeyboard(instance, false);
-
- if (currentInput != m_activeInput)
- switchActiveInput(currentInput);
-
- return 1;
- }
- break;
- }
-
- case kKey_ANPEventType:
- if (evt->data.key.action == kDown_ANPKeyAction) {
-
- //handle navigation keys
- if (evt->data.key.nativeCode >= kDpadUp_ANPKeyCode
- && evt->data.key.nativeCode <= kDpadCenter_ANPKeyCode) {
- return handleNavigation(evt->data.key.nativeCode) ? 1 : 0;
- }
-
- if (m_activeInput) {
- handleTextInput(m_activeInput, evt->data.key.nativeCode,
- evt->data.key.unichar);
- inval(instance, m_activeInput->rect, true);
- }
- }
- return 1;
-
- default:
- break;
- }
- return 0; // unknown or unhandled event
-}
-
-void FormPlugin::switchActiveInput(TextInput* newInput) {
- NPP instance = this->inst();
-
- if (m_activeInput) {
- inval(instance, m_activeInput->rect, true); // inval the old
- gWindowI.clearVisibleRects(instance);
- }
-
- m_activeInput = newInput; // set the new active input
-
- if (m_activeInput) {
- inval(instance, m_activeInput->rect, true); // inval the new
- scrollIntoView(m_activeInput);
- }
-}
-
-bool FormPlugin::handleNavigation(ANPKeyCode keyCode) {
- NPP instance = this->inst();
-
- gLogI.log(kDebug_ANPLogType, "----%p Recvd Nav Key %d", instance, keyCode);
-
- if (!m_activeInput) {
- gWindowI.showKeyboard(instance, true);
- switchActiveInput(&m_usernameInput);
- }
- else if (m_activeInput == &m_usernameInput) {
- if (keyCode == kDpadDown_ANPKeyCode) {
- switchActiveInput(&m_passwordInput);
- }
- else if (keyCode == kDpadCenter_ANPKeyCode)
- gWindowI.showKeyboard(instance, false);
- else if (keyCode == kDpadUp_ANPKeyCode)
- return false;
- }
- else if (m_activeInput == &m_passwordInput) {
- if (keyCode == kDpadUp_ANPKeyCode) {
- switchActiveInput(&m_usernameInput);
- }
- else if (keyCode == kDpadCenter_ANPKeyCode)
- gWindowI.showKeyboard(instance, false);
- else if (keyCode == kDpadDown_ANPKeyCode)
- return false;
- }
-
- return true;
-}
-
-void FormPlugin::handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar) {
- NPP instance = this->inst();
-
- //make sure the input field is in view
- scrollIntoView(input);
-
- //handle the delete operation
- if (keyCode == kDel_ANPKeyCode) {
- if (input->charPtr > 0) {
- input->charPtr--;
- }
- return;
- }
-
- //check to see that the input is not full
- if (input->charPtr >= (sizeof(input->text) - 1))
- return;
-
- //add the character
- input->text[input->charPtr] = static_cast<char>(unichar);
- input->charPtr++;
-
- gLogI.log(kDebug_ANPLogType, "----%p Text: %c", instance, unichar);
-}
-
-void FormPlugin::scrollIntoView(TextInput* input) {
- NPP instance = this->inst();
- PluginObject *obj = (PluginObject*) instance->pdata;
- NPWindow *window = obj->window;
-
- // find the textInput's global rect coordinates
- ANPRectI visibleRects[1];
- visibleRects[0].left = input->rect.left;
- visibleRects[0].top = input->rect.top;
- visibleRects[0].right = input->rect.right;
- visibleRects[0].bottom = input->rect.bottom;
-
- gWindowI.setVisibleRects(instance, visibleRects, 1);
-}
-
-TextInput* FormPlugin::validTap(int x, int y) {
-
- if (x > m_usernameInput.rect.left && x < m_usernameInput.rect.right &&
- y > m_usernameInput.rect.top && y < m_usernameInput.rect.bottom)
- return &m_usernameInput;
- else if (x >m_passwordInput.rect.left && x < m_passwordInput.rect.right &&
- y > m_passwordInput.rect.top && y < m_passwordInput.rect.bottom)
- return &m_passwordInput;
- else
- return NULL;
-}
diff --git a/samples/BrowserPlugin/jni/form/FormPlugin.h b/samples/BrowserPlugin/jni/form/FormPlugin.h
deleted file mode 100644
index 041ffb8..0000000
--- a/samples/BrowserPlugin/jni/form/FormPlugin.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PluginObject.h"
-
-#ifndef formPlugin__DEFINED
-#define formPlugin__DEFINED
-
-struct TextInput {
- ANPRectF rect;
- char text[30];
- uint32_t charPtr;
-};
-
-class FormPlugin : public SubPlugin {
-public:
- FormPlugin(NPP inst);
- virtual ~FormPlugin();
- virtual bool supportsDrawingModel(ANPDrawingModel);
- virtual int16 handleEvent(const ANPEvent* evt);
-private:
- void draw(ANPCanvas*);
- void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
-
- bool m_hasFocus;
-
- TextInput* m_activeInput;
- TextInput m_usernameInput;
- TextInput m_passwordInput;
-
- ANPPaint* m_paintInput;
- ANPPaint* m_paintActive;
- ANPPaint* m_paintText;
-
- ANPRectI m_visibleRect;
-
- void drawText(ANPCanvas*, TextInput);
- void drawPassword(ANPCanvas*, TextInput);
-
- bool handleNavigation(ANPKeyCode keyCode);
- void handleTextInput(TextInput* input, ANPKeyCode keyCode, int32_t unichar);
- void scrollIntoView(TextInput* input);
- void switchActiveInput(TextInput* input);
-
- ANPPaint* getPaint(TextInput*);
- TextInput* validTap(int x, int y);
-
-};
-
-#endif // formPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp
deleted file mode 100644
index 9ba8a32..0000000
--- a/samples/BrowserPlugin/jni/jni-bridge.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- *
- */
-#include <string.h>
-#include <jni.h>
-#include <JNIHelp.h>
-#include <utils/Log.h>
-
-#include "PluginObject.h"
-
-#define EXPORT __attribute__((visibility("default")))
-
-extern ANPEventInterfaceV0 gEventI;
-
-static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
-
- // send custom event
- ANPEvent event;
- event.inSize = sizeof(ANPEvent);
- event.eventType = kCustom_ANPEventType;
- event.data.other[0] = kSurfaceCreated_CustomEvent;
-
- gEventI.postEvent((NPP)npp, &event);
-}
-
-static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) {
- // send custom event
- ANPEvent event;
- event.inSize = sizeof(ANPEvent);
- event.eventType = kCustom_ANPEventType;
- event.data.other[0] = kSurfaceChanged_CustomEvent;
- event.data.other[1] = width;
- event.data.other[2] = height;
-
- gEventI.postEvent((NPP)npp, &event);
-}
-
-static void surfaceDestroyed(JNIEnv* env, jobject thiz, jint npp) {
- // send custom event
- ANPEvent event;
- event.inSize = sizeof(ANPEvent);
- event.eventType = kCustom_ANPEventType;
- event.data.other[0] = kSurfaceDestroyed_CustomEvent;
-
- gEventI.postEvent((NPP)npp, &event);
-}
-
-/*
- * JNI registration.
- */
-static JNINativeMethod gPaintSurfaceMethods[] = {
- { "nativeSurfaceCreated", "(I)V", (void*) surfaceCreated },
- { "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
- { "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
-};
-
-EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
-
- JNIEnv* env = NULL;
-
- if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- return -1;
- }
-
- jniRegisterNativeMethods(env, "com/android/sampleplugin/PaintSurface",
- gPaintSurfaceMethods, NELEM(gPaintSurfaceMethods));
-
- return JNI_VERSION_1_4;
-}
diff --git a/samples/BrowserPlugin/jni/main.cpp b/samples/BrowserPlugin/jni/main.cpp
deleted file mode 100644
index 3e8fee7..0000000
--- a/samples/BrowserPlugin/jni/main.cpp
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "main.h"
-#include "PluginObject.h"
-#include "AnimationPlugin.h"
-#include "AudioPlugin.h"
-#include "BackgroundPlugin.h"
-#include "FormPlugin.h"
-#include "NavigationPlugin.h"
-#include "PaintPlugin.h"
-#include "VideoPlugin.h"
-
-NPNetscapeFuncs* browser;
-JavaVM* gVM;
-
-#define EXPORT __attribute__((visibility("default")))
-
-NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
- char* argn[], char* argv[], NPSavedData* saved);
-NPError NPP_Destroy(NPP instance, NPSavedData** save);
-NPError NPP_SetWindow(NPP instance, NPWindow* window);
-NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
- NPBool seekable, uint16* stype);
-NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
-int32 NPP_WriteReady(NPP instance, NPStream* stream);
-int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
- void* buffer);
-void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
-void NPP_Print(NPP instance, NPPrint* platformPrint);
-int16 NPP_HandleEvent(NPP instance, void* event);
-void NPP_URLNotify(NPP instance, const char* URL, NPReason reason,
- void* notifyData);
-NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
-NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
-
-extern "C" {
-EXPORT NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env);
-EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value);
-EXPORT const char* NP_GetMIMEDescription(void);
-EXPORT void NP_Shutdown(void);
-};
-
-ANPAudioTrackInterfaceV0 gSoundI;
-ANPBitmapInterfaceV0 gBitmapI;
-ANPCanvasInterfaceV0 gCanvasI;
-ANPEventInterfaceV0 gEventI;
-ANPLogInterfaceV0 gLogI;
-ANPPaintInterfaceV0 gPaintI;
-ANPPathInterfaceV0 gPathI;
-ANPSurfaceInterfaceV0 gSurfaceI;
-ANPSystemInterfaceV0 gSystemI;
-ANPTypefaceInterfaceV0 gTypefaceI;
-ANPWindowInterfaceV0 gWindowI;
-
-#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
-#define DEBUG_PLUGIN_EVENTS 0
-
-NPError NP_Initialize(NPNetscapeFuncs* browserFuncs, NPPluginFuncs* pluginFuncs, void *java_env)
-{
- // Make sure we have a function table equal or larger than we are built against.
- if (browserFuncs->size < sizeof(NPNetscapeFuncs)) {
- return NPERR_GENERIC_ERROR;
- }
-
- // Copy the function table (structure)
- browser = (NPNetscapeFuncs*) malloc(sizeof(NPNetscapeFuncs));
- memcpy(browser, browserFuncs, sizeof(NPNetscapeFuncs));
-
- // Build the plugin function table
- pluginFuncs->version = 11;
- pluginFuncs->size = sizeof(pluginFuncs);
- pluginFuncs->newp = NPP_New;
- pluginFuncs->destroy = NPP_Destroy;
- pluginFuncs->setwindow = NPP_SetWindow;
- pluginFuncs->newstream = NPP_NewStream;
- pluginFuncs->destroystream = NPP_DestroyStream;
- pluginFuncs->asfile = NPP_StreamAsFile;
- pluginFuncs->writeready = NPP_WriteReady;
- pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
- pluginFuncs->print = NPP_Print;
- pluginFuncs->event = NPP_HandleEvent;
- pluginFuncs->urlnotify = NPP_URLNotify;
- pluginFuncs->getvalue = NPP_GetValue;
- pluginFuncs->setvalue = NPP_SetValue;
-
- static const struct {
- NPNVariable v;
- uint32_t size;
- ANPInterface* i;
- } gPairs[] = {
- { kAudioTrackInterfaceV0_ANPGetValue, sizeof(gSoundI), &gSoundI },
- { kBitmapInterfaceV0_ANPGetValue, sizeof(gBitmapI), &gBitmapI },
- { kCanvasInterfaceV0_ANPGetValue, sizeof(gCanvasI), &gCanvasI },
- { kEventInterfaceV0_ANPGetValue, sizeof(gEventI), &gEventI },
- { kLogInterfaceV0_ANPGetValue, sizeof(gLogI), &gLogI },
- { kPaintInterfaceV0_ANPGetValue, sizeof(gPaintI), &gPaintI },
- { kPathInterfaceV0_ANPGetValue, sizeof(gPathI), &gPathI },
- { kSurfaceInterfaceV0_ANPGetValue, sizeof(gSurfaceI), &gSurfaceI },
- { kSystemInterfaceV0_ANPGetValue, sizeof(gSystemI), &gSystemI },
- { kTypefaceInterfaceV0_ANPGetValue, sizeof(gTypefaceI), &gTypefaceI },
- { kWindowInterfaceV0_ANPGetValue, sizeof(gWindowI), &gWindowI },
- };
- for (size_t i = 0; i < ARRAY_COUNT(gPairs); i++) {
- gPairs[i].i->inSize = gPairs[i].size;
- NPError err = browser->getvalue(NULL, gPairs[i].v, gPairs[i].i);
- if (err) {
- return err;
- }
- }
-
- // store the JavaVM for the plugin
- JNIEnv* env = (JNIEnv*)java_env;
- env->GetJavaVM(&gVM);
-
- return NPERR_NO_ERROR;
-}
-
-void NP_Shutdown(void)
-{
-
-}
-
-const char *NP_GetMIMEDescription(void)
-{
- return "application/x-testbrowserplugin:tst:Test plugin mimetype is application/x-testbrowserplugin";
-}
-
-NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
- char* argn[], char* argv[], NPSavedData* saved)
-{
-
- /* BEGIN: STANDARD PLUGIN FRAMEWORK */
- PluginObject *obj = NULL;
-
- // Scripting functions appeared in NPAPI version 14
- if (browser->version >= 14) {
- instance->pdata = browser->createobject (instance, getPluginClass());
- obj = static_cast<PluginObject*>(instance->pdata);
- }
- /* END: STANDARD PLUGIN FRAMEWORK */
-
- // select the drawing model based on user input
- ANPDrawingModel model = kBitmap_ANPDrawingModel;
-
- for (int i = 0; i < argc; i++) {
- if (!strcmp(argn[i], "DrawingModel")) {
- if (!strcmp(argv[i], "Bitmap")) {
- model = kBitmap_ANPDrawingModel;
- }
- else if (!strcmp(argv[i], "Surface")) {
- model = kSurface_ANPDrawingModel;
- }
- gLogI.log(kDebug_ANPLogType, "------ %p DrawingModel is %d", instance, model);
- break;
- }
- }
-
- // notify the plugin API of the drawing model we wish to use. This must be
- // done prior to creating certain subPlugin objects (e.g. surfaceViews)
- NPError err = browser->setvalue(instance, kRequestDrawingModel_ANPSetValue,
- reinterpret_cast<void*>(model));
- if (err) {
- gLogI.log(kError_ANPLogType, "request model %d err %d", model, err);
- return err;
- }
-
- const char* path = gSystemI.getApplicationDataDirectory();
- if (path) {
- gLogI.log(kDebug_ANPLogType, "Application data dir is %s", path);
- } else {
- gLogI.log(kError_ANPLogType, "Can't find Application data dir");
- }
-
- // select the pluginType
- for (int i = 0; i < argc; i++) {
- if (!strcmp(argn[i], "PluginType")) {
- if (!strcmp(argv[i], "Animation")) {
- obj->pluginType = kAnimation_PluginType;
- obj->activePlugin = new BallAnimation(instance);
- }
- else if (!strcmp(argv[i], "Audio")) {
- obj->pluginType = kAudio_PluginType;
- obj->activePlugin = new AudioPlugin(instance);
- }
- else if (!strcmp(argv[i], "Background")) {
- obj->pluginType = kBackground_PluginType;
- obj->activePlugin = new BackgroundPlugin(instance);
- }
- else if (!strcmp(argv[i], "Form")) {
- obj->pluginType = kForm_PluginType;
- obj->activePlugin = new FormPlugin(instance);
- }
- else if (!strcmp(argv[i], "Navigation")) {
- obj->pluginType = kNavigation_PluginType;
- obj->activePlugin = new NavigationPlugin(instance);
- }
- else if (!strcmp(argv[i], "Paint")) {
- obj->pluginType = kPaint_PluginType;
- obj->activePlugin = new PaintPlugin(instance);
- }
- else if (!strcmp(argv[i], "Video")) {
- obj->pluginType = kVideo_PluginType;
- obj->activePlugin = new VideoPlugin(instance);
- }
- gLogI.log(kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
- break;
- }
- }
-
- // if no pluginType is specified then default to Animation
- if (!obj->pluginType) {
- gLogI.log(kError_ANPLogType, "------ %p No PluginType attribute was found", instance);
- obj->pluginType = kAnimation_PluginType;
- obj->activePlugin = new BallAnimation(instance);
- }
-
- // check to ensure the pluginType supports the model
- if (!obj->activePlugin->supportsDrawingModel(model)) {
- gLogI.log(kError_ANPLogType, "------ %p Unsupported DrawingModel (%d)", instance, model);
- return NPERR_GENERIC_ERROR;
- }
-
- // if the plugin uses the surface drawing model then set the java context
- if (model == kSurface_ANPDrawingModel) {
- SurfaceSubPlugin* surfacePlugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
-
- jobject context;
- NPError err = browser->getvalue(instance, kJavaContext_ANPGetValue,
- static_cast<void*>(&context));
- if (err) {
- gLogI.log(kError_ANPLogType, "request context err: %d", err);
- return err;
- }
-
- surfacePlugin->setContext(context);
- }
-
-
- return NPERR_NO_ERROR;
-}
-
-NPError NPP_Destroy(NPP instance, NPSavedData** save)
-{
- PluginObject *obj = (PluginObject*) instance->pdata;
- if (obj) {
- delete obj->activePlugin;
- browser->releaseobject(&obj->header);
- }
-
- return NPERR_NO_ERROR;
-}
-
-NPError NPP_SetWindow(NPP instance, NPWindow* window)
-{
- PluginObject *obj = (PluginObject*) instance->pdata;
-
- // Do nothing if browser didn't support NPN_CreateObject which would have created the PluginObject.
- if (obj != NULL) {
- obj->window = window;
- }
-
- browser->invalidaterect(instance, NULL);
-
- return NPERR_NO_ERROR;
-}
-
-NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
-{
- *stype = NP_ASFILEONLY;
- return NPERR_NO_ERROR;
-}
-
-NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
-{
- return NPERR_NO_ERROR;
-}
-
-int32 NPP_WriteReady(NPP instance, NPStream* stream)
-{
- return 0;
-}
-
-int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
-{
- return 0;
-}
-
-void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
-{
-}
-
-void NPP_Print(NPP instance, NPPrint* platformPrint)
-{
-}
-
-int16 NPP_HandleEvent(NPP instance, void* event)
-{
- PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
- const ANPEvent* evt = reinterpret_cast<const ANPEvent*>(event);
-
-#if DEBUG_PLUGIN_EVENTS
- switch (evt->eventType) {
- case kDraw_ANPEventType:
-
- if (evt->data.draw.model == kBitmap_ANPDrawingModel) {
-
- static ANPBitmapFormat currentFormat = -1;
- if (evt->data.draw.data.bitmap.format != currentFormat) {
- currentFormat = evt->data.draw.data.bitmap.format;
- gLogI.log(kDebug_ANPLogType, "---- %p Draw (bitmap)"
- " clip=%d,%d,%d,%d format=%d", instance,
- evt->data.draw.clip.left,
- evt->data.draw.clip.top,
- evt->data.draw.clip.right,
- evt->data.draw.clip.bottom,
- evt->data.draw.data.bitmap.format);
- }
- }
- break;
-
- case kKey_ANPEventType:
- gLogI.log(kDebug_ANPLogType, "---- %p Key action=%d"
- " code=%d vcode=%d unichar=%d repeat=%d mods=%x", instance,
- evt->data.key.action,
- evt->data.key.nativeCode,
- evt->data.key.virtualCode,
- evt->data.key.unichar,
- evt->data.key.repeatCount,
- evt->data.key.modifiers);
- break;
-
- case kLifecycle_ANPEventType:
- gLogI.log(kDebug_ANPLogType, "---- %p Lifecycle action=%d",
- instance, evt->data.lifecycle.action);
- break;
-
- case kTouch_ANPEventType:
- gLogI.log(kDebug_ANPLogType, "---- %p Touch action=%d [%d %d]",
- instance, evt->data.touch.action, evt->data.touch.x,
- evt->data.touch.y);
- break;
-
- case kMouse_ANPEventType:
- gLogI.log(kDebug_ANPLogType, "---- %p Mouse action=%d [%d %d]",
- instance, evt->data.mouse.action, evt->data.mouse.x,
- evt->data.mouse.y);
- break;
-
- case kVisibleRect_ANPEventType:
- gLogI.log(kDebug_ANPLogType, "---- %p VisibleRect [%d %d %d %d]",
- instance, evt->data.visibleRect.rect.left, evt->data.visibleRect.rect.top,
- evt->data.visibleRect.rect.right, evt->data.visibleRect.rect.bottom);
- break;
-
- default:
- gLogI.log(kError_ANPLogType, "---- %p Unknown Event [%d]",
- instance, evt->eventType);
- break;
- }
-#endif
-
- if(!obj->activePlugin) {
- gLogI.log(kError_ANPLogType, "the active plugin is null.");
- return 0; // unknown or unhandled event
- }
- else {
- return obj->activePlugin->handleEvent(evt);
- }
-}
-
-void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
-{
-
-}
-
-EXPORT NPError NP_GetValue(NPP instance, NPPVariable variable, void *value) {
-
- if (variable == NPPVpluginNameString) {
- const char **str = (const char **)value;
- *str = "Test Plugin";
- return NPERR_NO_ERROR;
- }
-
- if (variable == NPPVpluginDescriptionString) {
- const char **str = (const char **)value;
- *str = "Description of Test Plugin";
- return NPERR_NO_ERROR;
- }
-
- return NPERR_GENERIC_ERROR;
-}
-
-NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value)
-{
- if (variable == NPPVpluginScriptableNPObject) {
- void **v = (void **)value;
- PluginObject *obj = (PluginObject*) instance->pdata;
-
- if (obj)
- browser->retainobject(&obj->header);
-
- *v = &(obj->header);
- return NPERR_NO_ERROR;
- }
-
- if (variable == kJavaSurface_ANPGetValue) {
- //get the surface sub-plugin
- PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
- if (obj && obj->activePlugin) {
-
- if(obj->activePlugin->supportsDrawingModel(kSurface_ANPDrawingModel)) {
- SurfaceSubPlugin* plugin = static_cast<SurfaceSubPlugin*>(obj->activePlugin);
- jobject* surface = static_cast<jobject*>(value);
- *surface = plugin->getSurface();
- return NPERR_NO_ERROR;
- } else {
- gLogI.log(kError_ANPLogType,
- "-- %p Tried to retrieve surface for non-surface plugin",
- instance);
- }
- }
- }
-
- return NPERR_GENERIC_ERROR;
-}
-
-NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
-{
- return NPERR_GENERIC_ERROR;
-}
-
diff --git a/samples/BrowserPlugin/jni/main.h b/samples/BrowserPlugin/jni/main.h
deleted file mode 100644
index 66629e6..0000000
--- a/samples/BrowserPlugin/jni/main.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <npapi.h>
-#include <npfunctions.h>
-#include <npruntime.h>
-#include "android_npapi.h"
-#include "ANPSurface_npapi.h"
-#include "ANPSystem_npapi.h"
-
-extern NPNetscapeFuncs* browser;
-extern JavaVM* gVM;
diff --git a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp
deleted file mode 100644
index 99667a4..0000000
--- a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "NavigationPlugin.h"
-
-#include <stdio.h>
-#include <sys/time.h>
-#include <time.h>
-#include <math.h>
-#include <string.h>
-
-extern NPNetscapeFuncs* browser;
-extern ANPLogInterfaceV0 gLogI;
-extern ANPCanvasInterfaceV0 gCanvasI;
-extern ANPPaintInterfaceV0 gPaintI;
-extern ANPTypefaceInterfaceV0 gTypefaceI;
-extern ANPWindowInterfaceV0 gWindowI;
-
-
-static void inval(NPP instance) {
- browser->invalidaterect(instance, NULL);
-}
-
-static uint16 rnd16(float x, int inset) {
- int ix = (int)roundf(x) + inset;
- if (ix < 0) {
- ix = 0;
- }
- return static_cast<uint16>(ix);
-}
-
-static void inval(NPP instance, const ANPRectF& r, bool doAA) {
- const int inset = doAA ? -1 : 0;
-
- PluginObject *obj = reinterpret_cast<PluginObject*>(instance->pdata);
- NPRect inval;
- inval.left = rnd16(r.left, inset);
- inval.top = rnd16(r.top, inset);
- inval.right = rnd16(r.right, -inset);
- inval.bottom = rnd16(r.bottom, -inset);
- browser->invalidaterect(instance, &inval);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-NavigationPlugin::NavigationPlugin(NPP inst) : SubPlugin(inst) {
-
- m_hasFocus = false;
- m_activeNav = NULL;
-
- m_paintDisabled = gPaintI.newPaint();
- gPaintI.setFlags(m_paintDisabled, gPaintI.getFlags(m_paintDisabled) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintDisabled, 0xFFFFFFFF);
-
- m_paintActive = gPaintI.newPaint();
- gPaintI.setFlags(m_paintActive, gPaintI.getFlags(m_paintActive) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintActive, 0xFFFFFF00);
-
- //register for key events
- ANPEventFlags flags = kKey_ANPEventFlag;
- NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error selecting input events.");
- }
-}
-
-NavigationPlugin::~NavigationPlugin() {
- gPaintI.deletePaint(m_paintDisabled);
- gPaintI.deletePaint(m_paintActive);
-}
-
-bool NavigationPlugin::supportsDrawingModel(ANPDrawingModel model) {
- return (model == kBitmap_ANPDrawingModel);
-}
-
-void NavigationPlugin::drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip) {
- ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
-
- ANPRectF clipR;
- clipR.left = clip.left;
- clipR.top = clip.top;
- clipR.right = clip.right;
- clipR.bottom = clip.bottom;
- gCanvasI.clipRect(canvas, &clipR);
-
- draw(canvas);
- gCanvasI.deleteCanvas(canvas);
-}
-
-void NavigationPlugin::draw(ANPCanvas* canvas) {
- NPP instance = this->inst();
- PluginObject *obj = (PluginObject*) instance->pdata;
-
- const int W = obj->window->width;
- const int H = obj->window->height;
- const int Wm = W/2;
- const int Hm = H/2;
-
- // color the plugin canvas
- gCanvasI.drawColor(canvas, (m_hasFocus) ? 0xFFCDCDCD : 0xFF545454);
-
- // draw the nav up box (5 px from the top edge)
- m_navUp.left = Wm - 15;
- m_navUp.top = 5;
- m_navUp.right = m_navUp.left + 30;
- m_navUp.bottom = m_navUp.top + 30;
- gCanvasI.drawRect(canvas, &m_navUp, getPaint(&m_navUp));
-
- // draw the nav down box (5 px from the bottom edge)
- m_navDown.left = Wm - 15;
- m_navDown.top = H - (30 + 5);
- m_navDown.right = m_navDown.left + 30;
- m_navDown.bottom = m_navDown.top + 30;
- gCanvasI.drawRect(canvas, &m_navDown, getPaint(&m_navDown));
-
- // draw the nav left box (5 px from the left edge)
- m_navLeft.left = 5;
- m_navLeft.top = Hm - 15;
- m_navLeft.right = m_navLeft.left + 30;
- m_navLeft.bottom = m_navLeft.top + 30;
- gCanvasI.drawRect(canvas, &m_navLeft, getPaint(&m_navLeft));
-
- // draw the nav right box (5 px from the right edge)
- m_navRight.left = W - (30 + 5);
- m_navRight.top = Hm - 15;
- m_navRight.right = m_navRight.left + 30;
- m_navRight.bottom = m_navRight.top + 30;
- gCanvasI.drawRect(canvas, &m_navRight, getPaint(&m_navRight));
-
- // draw the nav center box
- m_navCenter.left = Wm - 15;
- m_navCenter.top = Hm - 15;
- m_navCenter.right = m_navCenter.left + 30;
- m_navCenter.bottom = m_navCenter.top + 30;
- gCanvasI.drawRect(canvas, &m_navCenter, getPaint(&m_navCenter));
-
- gLogI.log(kDebug_ANPLogType, "----%p Drawing Plugin", inst());
-}
-
-ANPPaint* NavigationPlugin::getPaint(ANPRectF* input) {
- return (input == m_activeNav) ? m_paintActive : m_paintDisabled;
-}
-
-int16 NavigationPlugin::handleEvent(const ANPEvent* evt) {
- NPP instance = this->inst();
-
- switch (evt->eventType) {
- case kDraw_ANPEventType:
- switch (evt->data.draw.model) {
- case kBitmap_ANPDrawingModel:
- drawPlugin(evt->data.draw.data.bitmap, evt->data.draw.clip);
- return 1;
- default:
- break; // unknown drawing model
- }
- break;
-
- case kLifecycle_ANPEventType:
- if (evt->data.lifecycle.action == kLoseFocus_ANPLifecycleAction) {
- gLogI.log(kDebug_ANPLogType, "----%p Loosing Focus", instance);
- m_hasFocus = false;
- inval(instance);
- return 1;
- }
- else if (evt->data.lifecycle.action == kGainFocus_ANPLifecycleAction) {
- gLogI.log(kDebug_ANPLogType, "----%p Gaining Focus", instance);
- m_hasFocus = true;
- inval(instance);
- return 1;
- }
- break;
-
- case kMouse_ANPEventType:
- return 1;
-
- case kKey_ANPEventType:
- if (evt->data.key.action == kDown_ANPKeyAction) {
- bool result = handleNavigation(evt->data.key.nativeCode);
- inval(instance);
- return result;
- }
- return 1;
-
- default:
- break;
- }
- return 0; // unknown or unhandled event
-}
-
-bool NavigationPlugin::handleNavigation(ANPKeyCode keyCode) {
- NPP instance = this->inst();
-
- gLogI.log(kDebug_ANPLogType, "----%p Received Key %d", instance, keyCode);
-
- switch (keyCode) {
- case kDpadUp_ANPKeyCode:
- m_activeNav = &m_navUp;
- break;
- case kDpadDown_ANPKeyCode:
- m_activeNav = &m_navDown;
- break;
- case kDpadLeft_ANPKeyCode:
- m_activeNav = &m_navLeft;
- break;
- case kDpadRight_ANPKeyCode:
- m_activeNav = &m_navRight;
- break;
- case kDpadCenter_ANPKeyCode:
- m_activeNav = &m_navCenter;
- break;
- case kQ_ANPKeyCode:
- case kDel_ANPKeyCode:
- m_activeNav = NULL;
- return false;
- default:
- m_activeNav = NULL;
- break;
- }
- return true;
-}
diff --git a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h b/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h
deleted file mode 100644
index ca12ae7..0000000
--- a/samples/BrowserPlugin/jni/navigation/NavigationPlugin.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PluginObject.h"
-
-#ifndef navigationPlugin__DEFINED
-#define navigationPlugin__DEFINED
-
-class NavigationPlugin : public SubPlugin {
-public:
- NavigationPlugin(NPP inst);
- virtual ~NavigationPlugin();
- virtual bool supportsDrawingModel(ANPDrawingModel);
- virtual int16 handleEvent(const ANPEvent* evt);
-private:
- void draw(ANPCanvas*);
- void drawPlugin(const ANPBitmap& bitmap, const ANPRectI& clip);
-
- bool m_hasFocus;
-
- ANPRectF* m_activeNav;
- ANPRectF m_navUp;
- ANPRectF m_navDown;
- ANPRectF m_navLeft;
- ANPRectF m_navRight;
- ANPRectF m_navCenter;
-
- ANPPaint* m_paintDisabled;
- ANPPaint* m_paintActive;
-
- bool handleNavigation(ANPKeyCode keyCode);
- ANPPaint* getPaint(ANPRectF*);
-};
-
-#endif // navigationPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
deleted file mode 100644
index 71b9f24..0000000
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PaintPlugin.h"
-
-#include <fcntl.h>
-#include <math.h>
-#include <string.h>
-
-extern NPNetscapeFuncs* browser;
-extern ANPLogInterfaceV0 gLogI;
-extern ANPCanvasInterfaceV0 gCanvasI;
-extern ANPPaintInterfaceV0 gPaintI;
-extern ANPPathInterfaceV0 gPathI;
-extern ANPSurfaceInterfaceV0 gSurfaceI;
-extern ANPSystemInterfaceV0 gSystemI;
-extern ANPTypefaceInterfaceV0 gTypefaceI;
-extern ANPWindowInterfaceV0 gWindowI;
-
-///////////////////////////////////////////////////////////////////////////////
-
-PaintPlugin::PaintPlugin(NPP inst) : SurfaceSubPlugin(inst) {
-
- m_isTouchActive = false;
- m_isTouchCurrentInput = true;
- m_activePaintColor = s_redColor;
-
- memset(&m_drawingSurface, 0, sizeof(m_drawingSurface));
- memset(&m_inputToggle, 0, sizeof(m_inputToggle));
- memset(&m_colorToggle, 0, sizeof(m_colorToggle));
- memset(&m_fullScreenToggle, 0, sizeof(m_fullScreenToggle));
- memset(&m_clearSurface, 0, sizeof(m_clearSurface));
-
- // initialize the drawing surface
- m_surface = NULL;
-
- // initialize the path
- m_touchPath = gPathI.newPath();
- if(!m_touchPath)
- gLogI.log(kError_ANPLogType, "----%p Unable to create the touch path", inst);
-
- // initialize the paint colors
- m_paintSurface = gPaintI.newPaint();
- gPaintI.setFlags(m_paintSurface, gPaintI.getFlags(m_paintSurface) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintSurface, 0xFFC0C0C0);
- gPaintI.setTextSize(m_paintSurface, 18);
-
- m_paintButton = gPaintI.newPaint();
- gPaintI.setFlags(m_paintButton, gPaintI.getFlags(m_paintButton) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(m_paintButton, 0xFFA8A8A8);
-
- // initialize the typeface (set the colors)
- ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
- gPaintI.setTypeface(m_paintSurface, tf);
- gTypefaceI.unref(tf);
-
- //register for touch events
- ANPEventFlags flags = kTouch_ANPEventFlag;
- NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error selecting input events.");
- }
-}
-
-PaintPlugin::~PaintPlugin() {
- gPathI.deletePath(m_touchPath);
- gPaintI.deletePaint(m_paintSurface);
- gPaintI.deletePaint(m_paintButton);
-
- setContext(NULL);
- destroySurface();
-}
-
-ANPCanvas* PaintPlugin::getCanvas(ANPRectI* dirtyRect) {
-
- ANPBitmap bitmap;
- JNIEnv* env = NULL;
- if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
- !gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
- return NULL;
- }
-
- ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
-
- // clip the canvas to the dirty rect b/c the surface is only required to
- // copy a minimum of the dirty rect and may copy more. The clipped canvas
- // however will never write to pixels outside of the clipped area.
- if (dirtyRect) {
- ANPRectF clipR;
- clipR.left = dirtyRect->left;
- clipR.top = dirtyRect->top;
- clipR.right = dirtyRect->right;
- clipR.bottom = dirtyRect->bottom;
- gCanvasI.clipRect(canvas, &clipR);
- }
-
- return canvas;
-}
-
-ANPCanvas* PaintPlugin::getCanvas(ANPRectF* dirtyRect) {
-
- ANPRectI newRect;
- newRect.left = (int) dirtyRect->left;
- newRect.top = (int) dirtyRect->top;
- newRect.right = (int) dirtyRect->right;
- newRect.bottom = (int) dirtyRect->bottom;
-
- return getCanvas(&newRect);
-}
-
-void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
- JNIEnv* env = NULL;
- if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
- gSurfaceI.unlock(env, m_surface);
- }
- gCanvasI.deleteCanvas(canvas);
-}
-
-void PaintPlugin::drawCleanPlugin(ANPCanvas* canvas) {
- NPP instance = this->inst();
- PluginObject *obj = (PluginObject*) instance->pdata;
-
- // if no canvas get a locked canvas
- if (!canvas)
- canvas = getCanvas();
-
- if (!canvas)
- return;
-
- const float buttonWidth = 60;
- const float buttonHeight = 30;
- const int W = obj->window->width;
- const int H = obj->window->height;
-
- // color the plugin canvas
- gCanvasI.drawColor(canvas, 0xFFCDCDCD);
-
- // get font metrics
- ANPFontMetrics fontMetrics;
- gPaintI.getFontMetrics(m_paintSurface, &fontMetrics);
-
- // draw the input toggle button
- m_inputToggle.left = 5;
- m_inputToggle.top = H - buttonHeight - 5;
- m_inputToggle.right = m_inputToggle.left + buttonWidth;
- m_inputToggle.bottom = m_inputToggle.top + buttonHeight;
- gCanvasI.drawRect(canvas, &m_inputToggle, m_paintButton);
- const char* inputText = m_isTouchCurrentInput ? "Touch" : "Mouse";
- gCanvasI.drawText(canvas, inputText, strlen(inputText), m_inputToggle.left + 5,
- m_inputToggle.top - fontMetrics.fTop, m_paintSurface);
-
- // draw the color selector button
- m_colorToggle.left = (W/3) - (buttonWidth/2);
- m_colorToggle.top = H - buttonHeight - 5;
- m_colorToggle.right = m_colorToggle.left + buttonWidth;
- m_colorToggle.bottom = m_colorToggle.top + buttonHeight;
- gCanvasI.drawRect(canvas, &m_colorToggle, m_paintButton);
- const char* colorText = getColorText();
- gCanvasI.drawText(canvas, colorText, strlen(colorText), m_colorToggle.left + 5,
- m_colorToggle.top - fontMetrics.fTop, m_paintSurface);
-
- // draw the full-screen toggle button
- m_fullScreenToggle.left = ((W*2)/3) - (buttonWidth/2);
- m_fullScreenToggle.top = H - buttonHeight - 5;
- m_fullScreenToggle.right = m_fullScreenToggle.left + buttonWidth;
- m_fullScreenToggle.bottom = m_fullScreenToggle.top + buttonHeight;
- gCanvasI.drawRect(canvas, &m_fullScreenToggle, m_paintButton);
- const char* fullScreenText = "Full";
- gCanvasI.drawText(canvas, fullScreenText, strlen(fullScreenText),
- m_fullScreenToggle.left + 5,
- m_fullScreenToggle.top - fontMetrics.fTop, m_paintSurface);
-
- // draw the clear canvas button
- m_clearSurface.left = W - buttonWidth - 5;
- m_clearSurface.top = H - buttonHeight - 5;
- m_clearSurface.right = m_clearSurface.left + buttonWidth;
- m_clearSurface.bottom = m_clearSurface.top + buttonHeight;
- gCanvasI.drawRect(canvas, &m_clearSurface, m_paintButton);
- const char* clearText = "Clear";
- gCanvasI.drawText(canvas, clearText, strlen(clearText), m_clearSurface.left + 5,
- m_clearSurface.top - fontMetrics.fTop, m_paintSurface);
-
- // draw the drawing surface box (5 px from the edge)
- m_drawingSurface.left = 5;
- m_drawingSurface.top = 5;
- m_drawingSurface.right = W - 5;
- m_drawingSurface.bottom = m_colorToggle.top - 5;
- gCanvasI.drawRect(canvas, &m_drawingSurface, m_paintSurface);
-
- // release the canvas
- releaseCanvas(canvas);
-}
-
-const char* PaintPlugin::getColorText() {
-
- if (m_activePaintColor == s_blueColor)
- return "Blue";
- else if (m_activePaintColor == s_greenColor)
- return "Green";
- else
- return "Red";
-}
-
-jobject PaintPlugin::getSurface() {
- if (m_surface) {
- return m_surface;
- }
-
- // load the appropriate java class and instantiate it
- JNIEnv* env = NULL;
- if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
- return NULL;
- }
-
- const char* className = "com.android.sampleplugin.PaintSurface";
- jclass paintClass = gSystemI.loadJavaClass(inst(), className);
-
- if(!paintClass) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
- return NULL;
- }
-
- PluginObject *obj = (PluginObject*) inst()->pdata;
- const int pW = obj->window->width;
- const int pH = obj->window->height;
-
- jmethodID constructor = env->GetMethodID(paintClass, "<init>", "(Landroid/content/Context;III)V");
- jobject paintSurface = env->NewObject(paintClass, constructor, m_context, (int)inst(), pW, pH);
-
- if(!paintSurface) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
- return NULL;
- }
-
- m_surface = env->NewGlobalRef(paintSurface);
- return m_surface;
-}
-
-void PaintPlugin::destroySurface() {
- JNIEnv* env = NULL;
- if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
-
- // detach the native code from the object
- jclass javaClass = env->GetObjectClass(m_surface);
- jmethodID invalMethod = env->GetMethodID(javaClass, "invalidateNPP", "()V");
- env->CallVoidMethod(m_surface, invalMethod);
-
- env->DeleteGlobalRef(m_surface);
- m_surface = NULL;
- }
-}
-
-int16 PaintPlugin::handleEvent(const ANPEvent* evt) {
- switch (evt->eventType) {
- case kTouch_ANPEventType: {
- float x = (float) evt->data.touch.x;
- float y = (float) evt->data.touch.y;
- if (kDown_ANPTouchAction == evt->data.touch.action && m_isTouchCurrentInput) {
-
- ANPRectF* rect = validTouch(evt->data.touch.x, evt->data.touch.y);
- if(rect == &m_drawingSurface) {
- m_isTouchActive = true;
- gPathI.moveTo(m_touchPath, x, y);
- paintTouch();
- return 1;
- }
-
- } else if (kMove_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
- gPathI.lineTo(m_touchPath, x, y);
- paintTouch();
- return 1;
- } else if (kUp_ANPTouchAction == evt->data.touch.action && m_isTouchActive) {
- gPathI.lineTo(m_touchPath, x, y);
- paintTouch();
- m_isTouchActive = false;
- gPathI.reset(m_touchPath);
- return 1;
- } else if (kCancel_ANPTouchAction == evt->data.touch.action) {
- m_isTouchActive = false;
- gPathI.reset(m_touchPath);
- return 1;
- } else if (kDoubleTap_ANPTouchAction == evt->data.touch.action) {
- gWindowI.requestCenterFitZoom(inst());
- return 1;
-
- }
- break;
- }
- case kMouse_ANPEventType: {
-
- if (m_isTouchActive)
- gLogI.log(kError_ANPLogType, "----%p Received unintended mouse event", inst());
-
- if (kDown_ANPMouseAction == evt->data.mouse.action) {
- ANPRectF* rect = validTouch(evt->data.mouse.x, evt->data.mouse.y);
- if (rect == &m_drawingSurface)
- paintMouse(evt->data.mouse.x, evt->data.mouse.y);
- else if (rect == &m_inputToggle)
- toggleInputMethod();
- else if (rect == &m_colorToggle)
- togglePaintColor();
- else if (rect == &m_fullScreenToggle)
- gWindowI.requestFullScreen(inst());
- else if (rect == &m_clearSurface)
- drawCleanPlugin();
- }
- return 1;
- }
- case kCustom_ANPEventType: {
-
- switch (evt->data.other[0]) {
- case kSurfaceCreated_CustomEvent:
- gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceCreated");
- /* The second draw call is added to cover up a problem in this
- plugin and is not a recommended usage pattern. This plugin
- does not correctly make partial updates to the double
- buffered surface and this second call hides that problem.
- */
- drawCleanPlugin();
- drawCleanPlugin();
- break;
- case kSurfaceChanged_CustomEvent: {
- gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceChanged");
-
- int width = evt->data.other[1];
- int height = evt->data.other[2];
-
- PluginObject *obj = (PluginObject*) inst()->pdata;
- const int pW = obj->window->width;
- const int pH = obj->window->height;
- // compare to the plugin's surface dimensions
- if (pW != width || pH != height)
- gLogI.log(kError_ANPLogType,
- "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
- inst(), pW, pH, width, height);
- break;
- }
- case kSurfaceDestroyed_CustomEvent:
- gLogI.log(kDebug_ANPLogType, " ---- customEvent: surfaceDestroyed");
- break;
- }
- break; // end KCustom_ANPEventType
- }
- default:
- break;
- }
- return 0; // unknown or unhandled event
-}
-
-ANPRectF* PaintPlugin::validTouch(int x, int y) {
-
- //convert to float
- float fx = (int) x;
- float fy = (int) y;
-
- if (fx > m_drawingSurface.left && fx < m_drawingSurface.right && fy > m_drawingSurface.top && fy < m_drawingSurface.bottom)
- return &m_drawingSurface;
- else if (fx > m_inputToggle.left && fx < m_inputToggle.right && fy > m_inputToggle.top && fy < m_inputToggle.bottom)
- return &m_inputToggle;
- else if (fx > m_colorToggle.left && fx < m_colorToggle.right && fy > m_colorToggle.top && fy < m_colorToggle.bottom)
- return &m_colorToggle;
- else if (fx > m_fullScreenToggle.left && fx < m_fullScreenToggle.right && fy > m_fullScreenToggle.top && fy < m_fullScreenToggle.bottom)
- return &m_fullScreenToggle;
- else if (fx > m_clearSurface.left && fx < m_clearSurface.right && fy > m_clearSurface.top && fy < m_clearSurface.bottom)
- return &m_clearSurface;
- else
- return NULL;
-}
-
-void PaintPlugin::toggleInputMethod() {
- m_isTouchCurrentInput = !m_isTouchCurrentInput;
-
- // lock only the input toggle and redraw the canvas
- ANPCanvas* lockedCanvas = getCanvas(&m_inputToggle);
- drawCleanPlugin(lockedCanvas);
-}
-
-void PaintPlugin::togglePaintColor() {
- if (m_activePaintColor == s_blueColor)
- m_activePaintColor = s_redColor;
- else if (m_activePaintColor == s_greenColor)
- m_activePaintColor = s_blueColor;
- else
- m_activePaintColor = s_greenColor;
-
- // lock only the color toggle and redraw the canvas
- ANPCanvas* lockedCanvas = getCanvas(&m_colorToggle);
- drawCleanPlugin(lockedCanvas);
-}
-
-void PaintPlugin::paintMouse(int x, int y) {
- //TODO do not paint outside the drawing surface
-
- //create the paint color
- ANPPaint* fillPaint = gPaintI.newPaint();
- gPaintI.setFlags(fillPaint, gPaintI.getFlags(fillPaint) | kAntiAlias_ANPPaintFlag);
- gPaintI.setStyle(fillPaint, kFill_ANPPaintStyle);
- gPaintI.setColor(fillPaint, m_activePaintColor);
-
- // handle the simple "mouse" paint (draw a point)
- ANPRectF point;
- point.left = (float) x-3;
- point.top = (float) y-3;
- point.right = (float) x+3;
- point.bottom = (float) y+3;
-
- // get a canvas that is only locked around the point and draw it
- ANPCanvas* canvas = getCanvas(&point);
- gCanvasI.drawOval(canvas, &point, fillPaint);
-
- // clean up
- releaseCanvas(canvas);
- gPaintI.deletePaint(fillPaint);
-}
-
-void PaintPlugin::paintTouch() {
- //TODO do not paint outside the drawing surface
-
- //create the paint color
- ANPPaint* strokePaint = gPaintI.newPaint();
- gPaintI.setFlags(strokePaint, gPaintI.getFlags(strokePaint) | kAntiAlias_ANPPaintFlag);
- gPaintI.setColor(strokePaint, m_activePaintColor);
- gPaintI.setStyle(strokePaint, kStroke_ANPPaintStyle);
- gPaintI.setStrokeWidth(strokePaint, 6.0);
- gPaintI.setStrokeCap(strokePaint, kRound_ANPPaintCap);
- gPaintI.setStrokeJoin(strokePaint, kRound_ANPPaintJoin);
-
- // handle the complex "touch" paint (draw a line)
- ANPRectF bounds;
- gPathI.getBounds(m_touchPath, &bounds);
-
- // get a canvas that is only locked around the point and draw the path
- ANPCanvas* canvas = getCanvas(&bounds);
- gCanvasI.drawPath(canvas, m_touchPath, strokePaint);
-
- // clean up
- releaseCanvas(canvas);
- gPaintI.deletePaint(strokePaint);
-}
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.h b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
deleted file mode 100644
index 035e51b..0000000
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PluginObject.h"
-#include <stdio.h>
-
-#ifndef paintPlugin__DEFINED
-#define paintPlugin__DEFINED
-
-class PaintPlugin : public SurfaceSubPlugin {
-public:
- PaintPlugin(NPP inst);
- virtual ~PaintPlugin();
- virtual int16 handleEvent(const ANPEvent* evt);
- virtual jobject getSurface();
-
-private:
- void drawCleanPlugin(ANPCanvas* canvas = NULL);
- ANPCanvas* getCanvas(ANPRectI* dirtyRect = NULL);
- ANPCanvas* getCanvas(ANPRectF* dirtyRect);
- const char* getColorText();
- void destroySurface();
- void paintMouse(int x, int y);
- void paintTouch();
- void releaseCanvas(ANPCanvas*);
- void toggleInputMethod();
- void togglePaintColor();
- ANPRectF* validTouch(int x, int y);
-
- bool m_isTouchActive;
- bool m_isTouchCurrentInput;
-
- jobject m_surface;
- ANPPath* m_touchPath;
-
- ANPRectF m_drawingSurface;
- ANPRectF m_inputToggle;
- ANPRectF m_colorToggle;
- ANPRectF m_fullScreenToggle;
- ANPRectF m_clearSurface;
-
- ANPPaint* m_paintSurface;
- ANPPaint* m_paintButton;
-
- ANPColor m_activePaintColor;
- static const ANPColor s_redColor = 0xFFFF0000;
- static const ANPColor s_greenColor = 0xFF00FF00;
- static const ANPColor s_blueColor = 0xFF0000FF;
-};
-
-#endif // paintPlugin__DEFINED
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
deleted file mode 100644
index f24295b..0000000
--- a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "VideoPlugin.h"
-#include "android_npapi.h"
-
-#include <stdio.h>
-#include <sys/time.h>
-#include <time.h>
-#include <math.h>
-#include <string.h>
-
-extern NPNetscapeFuncs* browser;
-extern ANPBitmapInterfaceV0 gBitmapI;
-extern ANPCanvasInterfaceV0 gCanvasI;
-extern ANPLogInterfaceV0 gLogI;
-extern ANPPaintInterfaceV0 gPaintI;
-extern ANPSurfaceInterfaceV0 gSurfaceI;
-extern ANPSystemInterfaceV0 gSystemI;
-extern ANPTypefaceInterfaceV0 gTypefaceI;
-extern ANPWindowInterfaceV0 gWindowI;
-
-///////////////////////////////////////////////////////////////////////////////
-
-VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
-
- // initialize the drawing surface
- m_surface = NULL;
-
- //register for touch events
- ANPEventFlags flags = kTouch_ANPEventFlag;
- NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
- if (err != NPERR_NO_ERROR) {
- gLogI.log(kError_ANPLogType, "Error selecting input events.");
- }
-}
-
-VideoPlugin::~VideoPlugin() {
- setContext(NULL);
- destroySurface();
-}
-
-jobject VideoPlugin::getSurface() {
-
- if (m_surface) {
- return m_surface;
- }
-
- // load the appropriate java class and instantiate it
- JNIEnv* env = NULL;
- if (gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to get env");
- return NULL;
- }
-
- const char* className = "com.android.sampleplugin.VideoSurface";
- jclass videoClass = gSystemI.loadJavaClass(inst(), className);
-
- if(!videoClass) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to load class");
- return NULL;
- }
-
- jmethodID constructor = env->GetMethodID(videoClass, "<init>", "(Landroid/content/Context;)V");
- jobject videoSurface = env->NewObject(videoClass, constructor, m_context);
-
- if(!videoSurface) {
- gLogI.log(kError_ANPLogType, " ---- getSurface: failed to construct object");
- return NULL;
- }
-
- m_surface = env->NewGlobalRef(videoSurface);
- return m_surface;
-}
-
-void VideoPlugin::destroySurface() {
- JNIEnv* env = NULL;
- if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
- env->DeleteGlobalRef(m_surface);
- m_surface = NULL;
- }
-}
-
-int16 VideoPlugin::handleEvent(const ANPEvent* evt) {
- switch (evt->eventType) {
- case kLifecycle_ANPEventType: {
- switch (evt->data.lifecycle.action) {
- case kEnterFullScreen_ANPLifecycleAction:
- gLogI.log(kDebug_ANPLogType, " ---- %p entering fullscreen", inst());
- break;
- case kExitFullScreen_ANPLifecycleAction:
- gLogI.log(kDebug_ANPLogType, " ---- %p exiting fullscreen", inst());
- break;
- }
- break; // end kLifecycle_ANPEventType
- }
- case kDraw_ANPEventType:
- gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
- break;
- case kTouch_ANPEventType:
- if (kDown_ANPTouchAction == evt->data.touch.action) {
- gLogI.log(kDebug_ANPLogType, " ------ %p requesting fullscreen mode", inst());
- gWindowI.requestFullScreen(inst());
- }
- return 1;
- case kKey_ANPEventType:
- gLogI.log(kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
- break;
- default:
- break;
- }
- return 0; // unknown or unhandled event
-}
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.h b/samples/BrowserPlugin/jni/video/VideoPlugin.h
deleted file mode 100644
index 701e2d0..0000000
--- a/samples/BrowserPlugin/jni/video/VideoPlugin.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "PluginObject.h"
-
-#ifndef videoPlugin__DEFINED
-#define videoPlugin__DEFINED
-
-class VideoPlugin : public SurfaceSubPlugin {
-public:
- VideoPlugin(NPP inst);
- virtual ~VideoPlugin();
- virtual int16 handleEvent(const ANPEvent* evt);
- virtual jobject getSurface();
-
-private:
- void destroySurface();
-
- jobject m_surface;
-};
-
-#endif // videoPlugin__DEFINED
diff --git a/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png b/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png
deleted file mode 100755
index 4d9d559..0000000
--- a/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png
+++ /dev/null
Binary files differ
diff --git a/samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png b/samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png
deleted file mode 100755
index 47c79d1..0000000
--- a/samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png
+++ /dev/null
Binary files differ
diff --git a/samples/BrowserPlugin/res/values/strings.xml b/samples/BrowserPlugin/res/values/strings.xml
deleted file mode 100644
index 1f8dd49..0000000
--- a/samples/BrowserPlugin/res/values/strings.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2009 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.
--->
-<resources>
- <string name="sample_browser_plugin">Sample Browser Plugin</string>
-</resources>
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java
deleted file mode 100644
index 5af8c8e..0000000
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundSurface.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.android.sampleplugin;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.widget.TextView;
-
-public class BackgroundSurface extends TextView {
-
- public BackgroundSurface(Context context) {
- super(context);
-
- this.setBackgroundColor(Color.BLACK);
- this.setTextColor(Color.WHITE);
- this.setText("This is a java background plugin");
-
- // ensure that the view system is aware that we will be drawing
- this.setWillNotDraw(false);
- }
-}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundTest.java b/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundTest.java
deleted file mode 100644
index 1f6b0d4..0000000
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/BackgroundTest.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.android.sampleplugin;
-
-public class BackgroundTest {
-
- public BackgroundTest() {}
-
- public int addInt(int x, int y) {
- return x + y;
- }
-
-}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java
deleted file mode 100644
index 9582bcc..0000000
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/PaintSurface.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.android.sampleplugin;
-
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.SurfaceHolder.Callback;
-
-public class PaintSurface extends SurfaceView {
-
- static {
- //needed for jni calls
- System.loadLibrary("sampleplugin");
- }
-
- private final int npp;
-
- private boolean validNPP = true;
- private Object nppLock = new Object();
-
- public PaintSurface(Context context, int NPP, int width, int height) {
- super(context);
-
- this.npp = NPP;
-
- this.getHolder().setFormat(PixelFormat.RGBA_8888);
- this.getHolder().addCallback(new Callback() {
-
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- synchronized (nppLock) {
- if (validNPP) {
- nativeSurfaceChanged(npp, format, width, height);
- }
- }
- }
-
- public void surfaceCreated(SurfaceHolder holder) {
- synchronized (nppLock) {
- if (validNPP) {
- nativeSurfaceCreated(npp);
- }
- }
- }
-
- public void surfaceDestroyed(SurfaceHolder holder) {
- synchronized (nppLock) {
- if (validNPP) {
- nativeSurfaceDestroyed(npp);
- }
- }
- }
- });
-
- // sets the plugin's surface to a fixed size
- this.getHolder().setFixedSize(width, height);
-
- // ensure that the view system is aware that we will be drawing
- this.setWillNotDraw(false);
- }
-
- // called by JNI
- private void invalidateNPP() {
- synchronized (nppLock) {
- validNPP = false;
- }
- }
-
- private native void nativeSurfaceCreated(int npp);
- private native void nativeSurfaceChanged(int npp, int format, int width, int height);
- private native void nativeSurfaceDestroyed(int npp);
-}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java
deleted file mode 100644
index b5b728e..0000000
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePlugin.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.android.sampleplugin;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class SamplePlugin extends Service {
-
- @Override
- public IBinder onBind(Intent intent) {
- // TODO Auto-generated method stub
- return null;
- }
-}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java b/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java
deleted file mode 100644
index a3c80cf..0000000
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/VideoSurface.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package com.android.sampleplugin;
-
-import com.android.sampleplugin.graphics.CubeRenderer;
-
-import android.content.Context;
-import android.opengl.GLSurfaceView;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.MediaController;
-import android.widget.VideoView;
-
-public class VideoSurface extends FrameLayout {
-
- public VideoSurface(Context context) {
- super(context);
-
- LayoutParams fp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
- this.setLayoutParams(fp);
-
-// VideoView video = new VideoView(context);
-// LayoutParams vp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
-// vp.setLayoutParams(vp);
-
- GLSurfaceView gl = new GLSurfaceView(context);
- LayoutParams gp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
- gl.setLayoutParams(gp);
-
- this.addView(gl);
-// this.addView(video);
-
- // Tell the cube renderer that we want to render a translucent version
- // of the cube:
- gl.setRenderer(new CubeRenderer(false));
- gl.setWindowType(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY);
-
-// video.setVideoPath("/sdcard/test_video.3gp");
-// video.setMediaController(new MediaController(context));
-// video.requestFocus();
-
- // ensure that the view system is aware that we will be drawing
- this.setWillNotDraw(false);
- }
-}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/Cube.java b/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/Cube.java
deleted file mode 100644
index 9ad1410..0000000
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/Cube.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2009 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.android.sampleplugin.graphics;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.IntBuffer;
-
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * A vertex shaded cube.
- */
-class Cube
-{
- public Cube()
- {
- int one = 0x10000;
- int vertices[] = {
- -one, -one, -one,
- one, -one, -one,
- one, one, -one,
- -one, one, -one,
- -one, -one, one,
- one, -one, one,
- one, one, one,
- -one, one, one,
- };
-
- int colors[] = {
- 0, 0, 0, one,
- one, 0, 0, one,
- one, one, 0, one,
- 0, one, 0, one,
- 0, 0, one, one,
- one, 0, one, one,
- one, one, one, one,
- 0, one, one, one,
- };
-
- byte indices[] = {
- 0, 4, 5, 0, 5, 1,
- 1, 5, 6, 1, 6, 2,
- 2, 6, 7, 2, 7, 3,
- 3, 7, 4, 3, 4, 0,
- 4, 7, 6, 4, 6, 5,
- 3, 0, 1, 3, 1, 2
- };
-
- // Buffers to be passed to gl*Pointer() functions
- // must be direct, i.e., they must be placed on the
- // native heap where the garbage collector cannot
- // move them.
- //
- // Buffers with multi-byte datatypes (e.g., short, int, float)
- // must have their byte order set to native order
-
- ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
- vbb.order(ByteOrder.nativeOrder());
- mVertexBuffer = vbb.asIntBuffer();
- mVertexBuffer.put(vertices);
- mVertexBuffer.position(0);
-
- ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
- cbb.order(ByteOrder.nativeOrder());
- mColorBuffer = cbb.asIntBuffer();
- mColorBuffer.put(colors);
- mColorBuffer.position(0);
-
- mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
- mIndexBuffer.put(indices);
- mIndexBuffer.position(0);
- }
-
- public void draw(GL10 gl)
- {
- gl.glFrontFace(gl.GL_CW);
- gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
- gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
- gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
- }
-
- private IntBuffer mVertexBuffer;
- private IntBuffer mColorBuffer;
- private ByteBuffer mIndexBuffer;
-}
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/CubeRenderer.java b/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/CubeRenderer.java
deleted file mode 100644
index 246ac15..0000000
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/graphics/CubeRenderer.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2009 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.android.sampleplugin.graphics;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-import android.opengl.GLSurfaceView;
-
-/**
- * Render a pair of tumbling cubes.
- */
-
-public class CubeRenderer implements GLSurfaceView.Renderer {
- public CubeRenderer(boolean useTranslucentBackground) {
- mTranslucentBackground = useTranslucentBackground;
- mCube = new Cube();
- }
-
- public void onDrawFrame(GL10 gl) {
- /*
- * Usually, the first thing one might want to do is to clear
- * the screen. The most efficient way of doing this is to use
- * glClear().
- */
-
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-
- /*
- * Now we're ready to draw some 3D objects
- */
-
- gl.glMatrixMode(GL10.GL_MODELVIEW);
- gl.glLoadIdentity();
- gl.glTranslatef(0, 0, -3.0f);
- gl.glRotatef(mAngle, 0, 1, 0);
- gl.glRotatef(mAngle*0.25f, 1, 0, 0);
-
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
-
- mCube.draw(gl);
-
- gl.glRotatef(mAngle*2.0f, 0, 1, 1);
- gl.glTranslatef(0.5f, 0.5f, 0.5f);
-
- mCube.draw(gl);
-
- mAngle += 1.2f;
- }
-
- public void onSurfaceChanged(GL10 gl, int width, int height) {
- gl.glViewport(0, 0, width, height);
-
- /*
- * Set our projection matrix. This doesn't have to be done
- * each time we draw, but usually a new projection needs to
- * be set when the viewport is resized.
- */
-
- float ratio = (float) width / height;
- gl.glMatrixMode(GL10.GL_PROJECTION);
- gl.glLoadIdentity();
- gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
- }
-
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- /*
- * By default, OpenGL enables features that improve quality
- * but reduce performance. One might want to tweak that
- * especially on software renderer.
- */
- gl.glDisable(GL10.GL_DITHER);
-
- /*
- * Some one-time OpenGL initialization can be made here
- * probably based on features of this particular context
- */
- gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
- GL10.GL_FASTEST);
-
- if (mTranslucentBackground) {
- gl.glClearColor(0,0,0,0);
- } else {
- gl.glClearColor(1,1,1,1);
- }
- gl.glEnable(GL10.GL_CULL_FACE);
- gl.glShadeModel(GL10.GL_SMOOTH);
- gl.glEnable(GL10.GL_DEPTH_TEST);
- }
- private boolean mTranslucentBackground;
- private Cube mCube;
- private float mAngle;
-}
diff --git a/samples/ContactManager/AndroidManifest.xml b/samples/ContactManager/AndroidManifest.xml
index abf5669..60fca32 100644
--- a/samples/ContactManager/AndroidManifest.xml
+++ b/samples/ContactManager/AndroidManifest.xml
@@ -17,6 +17,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.contactmanager"
android:versionCode="1" android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="5" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+
<application android:label="@string/app_name" android:icon="@drawable/icon">
<activity android:name=".ContactManager" android:label="@string/app_name">
<intent-filter>
@@ -26,10 +32,5 @@
</activity>
<activity android:name="ContactAdder" android:label="@string/addContactTitle">
</activity>
-
</application>
- <uses-sdk android:minSdkVersion="5" android:targetSdkVersion="5" />
- <uses-permission android:name="android.permission.GET_ACCOUNTS" />
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <uses-permission android:name="android.permission.WRITE_CONTACTS" />
</manifest>
diff --git a/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java b/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
index d96b644..e27ee56 100644
--- a/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
+++ b/samples/GlobalTime/src/com/android/globaltime/GlobalTime.java
@@ -898,7 +898,7 @@
// The '2' key zooms out
case KeyEvent.KEYCODE_2:
- if (!mAlphaKeySet && !mDisplayWorldFlat) {
+ if (!mAlphaKeySet && !mDisplayWorldFlat && mInitialized) {
mGLView.zoom(-2);
handled = true;
}
@@ -906,7 +906,7 @@
// The '8' key zooms in
case KeyEvent.KEYCODE_8:
- if (!mAlphaKeySet && !mDisplayWorldFlat) {
+ if (!mAlphaKeySet && !mDisplayWorldFlat && mInitialized) {
mGLView.zoom(2);
handled = true;
}
diff --git a/samples/JetBoy/AndroidManifest.xml b/samples/JetBoy/AndroidManifest.xml
index bba069d..d0d4173 100755
--- a/samples/JetBoy/AndroidManifest.xml
+++ b/samples/JetBoy/AndroidManifest.xml
@@ -20,6 +20,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.jetboy" android:versionCode="1"
android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3"></uses-sdk>
+
<application android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
@@ -33,5 +36,4 @@
</intent-filter>
</activity>
</application>
- <uses-sdk android:minSdkVersion="3"></uses-sdk>
</manifest>
diff --git a/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java b/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
index a4ffef5..15c5923 100644
--- a/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
+++ b/samples/LunarLander/src/com/example/android/lunarlander/LunarLander.java
@@ -21,7 +21,6 @@
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.Window;
import android.widget.TextView;
import com.example.android.lunarlander.LunarView.LunarThread;
@@ -58,7 +57,7 @@
/**
* Invoked during init to give the Activity a chance to set up its Menu.
- *
+ *
* @param menu the Menu to which entries may be added
* @return true
*/
@@ -79,7 +78,7 @@
/**
* Invoked when the user selects an item from the Menu.
- *
+ *
* @param item the Menu entry which was selected
* @return true if the Menu item was legit (and we consumed it), false
* otherwise
@@ -116,7 +115,7 @@
/**
* Invoked when the Activity is created.
- *
+ *
* @param savedInstanceState a Bundle containing state saved from a previous
* execution, or null if this is a new execution
*/
@@ -157,7 +156,7 @@
/**
* Notification that something is about to happen, to give the Activity a
* chance to save state.
- *
+ *
* @param outState a Bundle into which this Activity should save its state
*/
@Override
diff --git a/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java b/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
index c52c7ab..2a46147 100644
--- a/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
+++ b/samples/LunarLander/src/com/example/android/lunarlander/LunarView.java
@@ -37,7 +37,7 @@
/**
* View that draws, takes keystrokes, etc. for a simple LunarLander game.
- *
+ *
* Has a mode which RUNNING, PAUSED, etc. Has a x, y, dx, dy, ... capturing the
* current ship physics. All x/y etc. are measured with (0,0) at the lower left.
* updatePhysics() advances the physics based on realtime. draw() renders the
@@ -112,14 +112,14 @@
/**
* Current height of the surface/canvas.
- *
+ *
* @see #setSurfaceSize
*/
private int mCanvasHeight = 1;
/**
* Current width of the surface/canvas.
- *
+ *
* @see #setSurfaceSize
*/
private int mCanvasWidth = 1;
@@ -321,7 +321,7 @@
* Restores game state from the indicated Bundle. Typically called when
* the Activity is being restored after having been previously
* destroyed.
- *
+ *
* @param savedState Bundle containing the game state
*/
public synchronized void restoreState(Bundle savedState) {
@@ -372,7 +372,7 @@
/**
* Dump game state to the provided Bundle. Typically called when the
* Activity is being suspended.
- *
+ *
* @return Bundle with this view's state
*/
public Bundle saveState(Bundle map) {
@@ -400,7 +400,7 @@
/**
* Sets the current difficulty.
- *
+ *
* @param difficulty
*/
public void setDifficulty(int difficulty) {
@@ -423,7 +423,7 @@
* Passing true allows the thread to run; passing false will shut it
* down if it's already running. Calling start() after this was most
* recently called with false will result in an immediate shutdown.
- *
+ *
* @param b true to run, false to shut down
*/
public void setRunning(boolean b) {
@@ -433,7 +433,7 @@
/**
* Sets the game mode. That is, whether we are running, paused, in the
* failure state, in the victory state, etc.
- *
+ *
* @see #setState(int, CharSequence)
* @param mode one of the STATE_* constants
*/
@@ -446,7 +446,7 @@
/**
* Sets the game mode. That is, whether we are running, paused, in the
* failure state, in the victory state, etc.
- *
+ *
* @param mode one of the STATE_* constants
* @param message string to add to screen or null
*/
@@ -509,7 +509,7 @@
mCanvasHeight = height;
// don't forget to resize the background image
- mBackgroundImage = mBackgroundImage.createScaledBitmap(
+ mBackgroundImage = Bitmap.createScaledBitmap(
mBackgroundImage, width, height, true);
}
}
@@ -527,7 +527,7 @@
/**
* Handles a key-down event.
- *
+ *
* @param keyCode the key that was pressed
* @param msg the original event object
* @return true
@@ -539,8 +539,6 @@
if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) okStart = true;
if (keyCode == KeyEvent.KEYCODE_S) okStart = true;
- boolean center = (keyCode == KeyEvent.KEYCODE_DPAD_UP);
-
if (okStart
&& (mMode == STATE_READY || mMode == STATE_LOSE || mMode == STATE_WIN)) {
// ready-to-start -> start
@@ -579,7 +577,7 @@
/**
* Handles a key-up event.
- *
+ *
* @param keyCode the key that was pressed
* @param msg the original event object
* @return true if the key was handled and consumed, or else false
@@ -807,7 +805,7 @@
/**
* Fetches the animation thread corresponding to this LunarView.
- *
+ *
* @return the animation thread
*/
public LunarThread getThread() {
diff --git a/samples/MultiResolution/AndroidManifest.xml b/samples/MultiResolution/AndroidManifest.xml
index 4719069..0ebb55c 100644
--- a/samples/MultiResolution/AndroidManifest.xml
+++ b/samples/MultiResolution/AndroidManifest.xml
@@ -23,6 +23,10 @@
<uses-permission
android:name="android.permission.INTERNET"/>
+ <uses-sdk
+ android:minSdkVersion="3"
+ android:targetSdkVersion="4"/>
+
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
@@ -42,8 +46,4 @@
</application>
- <uses-sdk
- android:minSdkVersion="3"
- android:targetSdkVersion="4"/>
-
</manifest>
diff --git a/samples/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
index b87dfe3..83e5732 100644
--- a/samples/NotePad/AndroidManifest.xml
+++ b/samples/NotePad/AndroidManifest.xml
@@ -22,6 +22,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.notepad" >
+ <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
+
<application android:icon="@drawable/app_notes"
android:label="@string/app_name" >
<provider android:name="NotePadProvider"
@@ -107,6 +109,4 @@
</application>
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4"/>
</manifest>
-
diff --git a/samples/SampleSyncAdapter/AndroidManifest.xml b/samples/SampleSyncAdapter/AndroidManifest.xml
index 7f9f83b..202ed0e 100644
--- a/samples/SampleSyncAdapter/AndroidManifest.xml
+++ b/samples/SampleSyncAdapter/AndroidManifest.xml
@@ -45,7 +45,9 @@
android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission
android:name="android.permission.WRITE_SYNC_SETTINGS" />
-
+
+ <uses-sdk android:minSdkVersion="5" />
+
<application
android:icon="@drawable/icon"
android:label="@string/label">
@@ -87,6 +89,4 @@
-->
</activity>
</application>
- <uses-sdk
- android:minSdkVersion="5" />
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/samples/Spinner/AndroidManifest.xml b/samples/Spinner/AndroidManifest.xml
index f1accf8..719a022 100644
--- a/samples/Spinner/AndroidManifest.xml
+++ b/samples/Spinner/AndroidManifest.xml
@@ -26,6 +26,12 @@
package="com.android.example.spinner"
android:versionCode="1"
android:versionName="1.0">
+
+ <!--
+ Requires a minimum platform version of Android-3 (SDK 1.5) to run
+ -->
+ <uses-sdk android:minSdkVersion="3"/>
+
<!--
Sets the application's user-readable label
-->
@@ -45,9 +51,5 @@
</activity>
</application>
- <!--
- Requires a minimum platform version of Android-3 (SDK 1.5) to run
- -->
- <uses-sdk android:minSdkVersion="3"/>
</manifest>
diff --git a/samples/TicTacToeMain/AndroidManifest.xml b/samples/TicTacToeMain/AndroidManifest.xml
index 54654f9..077eaa7 100755
--- a/samples/TicTacToeMain/AndroidManifest.xml
+++ b/samples/TicTacToeMain/AndroidManifest.xml
@@ -19,6 +19,9 @@
package="com.example.android.tictactoe"
android:versionCode="1"
android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="8" />
+
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
@@ -34,6 +37,4 @@
</application>
- <uses-sdk android:minSdkVersion="8" />
-
</manifest>
diff --git a/samples/Wiktionary/AndroidManifest.xml b/samples/Wiktionary/AndroidManifest.xml
index 1641a8b..741874b 100644
--- a/samples/Wiktionary/AndroidManifest.xml
+++ b/samples/Wiktionary/AndroidManifest.xml
@@ -18,6 +18,12 @@
package="com.example.android.wiktionary"
android:versionCode="1"
android:versionName="1.0">
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
+
+ <meta-data android:name="android.app.default_searchable" android:value=".LookupActivity" />
+
<application android:icon="@drawable/app_icon" android:label="@string/app_name"
android:description="@string/app_descrip">
@@ -62,9 +68,4 @@
</application>
- <meta-data android:name="android.app.default_searchable" android:value=".LookupActivity" />
-
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
-
</manifest>
diff --git a/samples/WiktionarySimple/AndroidManifest.xml b/samples/WiktionarySimple/AndroidManifest.xml
index c6b8724..b9935f4 100644
--- a/samples/WiktionarySimple/AndroidManifest.xml
+++ b/samples/WiktionarySimple/AndroidManifest.xml
@@ -19,6 +19,9 @@
android:versionCode="1"
android:versionName="1.0">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
+
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
<!-- Broadcast Receiver that will process AppWidget updates -->
@@ -35,7 +38,4 @@
</application>
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />
-
</manifest>
diff --git a/sdk/plat_tools_source.properties b/sdk/plat_tools_source.properties
index f23e52a..3f98b10 100644
--- a/sdk/plat_tools_source.properties
+++ b/sdk/plat_tools_source.properties
@@ -1,2 +1,2 @@
Pkg.UserSrc=false
-Pkg.Revision=3
+Pkg.Revision=8
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index 451d046..1928c73 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -315,19 +315,10 @@
self.SendCommand("wait-for-device")
# Now the device is there, but may not be running.
# Query the package manager with a basic command
- pm_found = False
- attempts = 0
- wait_period = 5
- while not pm_found and (attempts*wait_period) < wait_time:
- # assume the 'adb shell pm path android' command will always
- # return 'package: something' in the success case
- output = self.SendShellCommand("pm path android", retry_count=1)
- if "package:" in output:
- pm_found = True
- else:
- time.sleep(wait_period)
- attempts += 1
- if not pm_found:
+ try:
+ self._WaitForShellCommandContents("pm path android", "package:",
+ wait_time)
+ except errors.WaitForResponseTimedOutError:
raise errors.WaitForResponseTimedOutError(
"Package manager did not respond after %s seconds" % wait_time)
@@ -344,28 +335,88 @@
instrumentation_path = "%s/%s" % (package_name, runner_name)
logger.Log("Waiting for instrumentation to be present")
# Query the package manager
- inst_found = False
- attempts = 0
- wait_period = 5
- while not inst_found and (attempts*wait_period) < wait_time:
- # assume the 'adb shell pm list instrumentation'
- # return 'instrumentation: something' in the success case
- try:
- output = self.SendShellCommand("pm list instrumentation | grep %s"
- % instrumentation_path, retry_count=1)
- if "instrumentation:" in output:
- inst_found = True
- except errors.AbortError, e:
- # ignore
- pass
- if not inst_found:
- time.sleep(wait_period)
- attempts += 1
- if not inst_found:
+ try:
+ command = "pm list instrumentation | grep %s" % instrumentation_path
+ self._WaitForShellCommandContents(command, "instrumentation:", wait_time,
+ raise_abort=False)
+ except errors.WaitForResponseTimedOutError :
logger.Log(
"Could not find instrumentation %s on device. Does the "
"instrumentation in test's AndroidManifest.xml match definition"
"in test_defs.xml?" % instrumentation_path)
+ raise
+
+ def WaitForProcess(self, name, wait_time=120):
+ """Wait until a process is running on the device.
+
+ Args:
+ name: the process name as it appears in `ps`
+ wait_time: time in seconds to wait
+
+ Raises:
+ WaitForResponseTimedOutError if wait_time elapses and the process is
+ still not running
+ """
+ logger.Log("Waiting for process %s" % name)
+ self.SendCommand("wait-for-device")
+ self._WaitForShellCommandContents("ps", name, wait_time)
+
+ def WaitForProcessEnd(self, name, wait_time=120):
+ """Wait until a process is no longer running on the device.
+
+ Args:
+ name: the process name as it appears in `ps`
+ wait_time: time in seconds to wait
+
+ Raises:
+ WaitForResponseTimedOutError if wait_time elapses and the process is
+ still running
+ """
+ logger.Log("Waiting for process %s to end" % name)
+ self._WaitForShellCommandContents("ps", name, wait_time, invert=True)
+
+ def _WaitForShellCommandContents(self, command, expected, wait_time,
+ raise_abort=True, invert=False):
+ """Wait until the response to a command contains a given output.
+
+ Assumes that a only successful execution of "adb shell <command>" contains
+ the substring expected. Assumes that a device is present.
+
+ Args:
+ command: adb shell command to execute
+ expected: the string that should appear to consider the
+ command successful.
+ wait_time: time in seconds to wait
+ raise_abort: if False, retry when executing the command raises an
+ AbortError, rather than failing.
+ invert: if True, wait until the command output no longer contains the
+ expected contents.
+
+ Raises:
+ WaitForResponseTimedOutError: If wait_time elapses and the command has not
+ returned an output containing expected yet.
+ """
+ # Query the device with the command
+ success = False
+ attempts = 0
+ wait_period = 5
+ while not success and (attempts*wait_period) < wait_time:
+ # assume the command will always contain expected in the success case
+ try:
+ output = self.SendShellCommand(command, retry_count=1)
+ if ((not invert and expected in output)
+ or (invert and expected not in output)):
+ success = True
+ except errors.AbortError, e:
+ if raise_abort:
+ raise
+ # ignore otherwise
+
+ if not success:
+ time.sleep(wait_period)
+ attempts += 1
+
+ if not success:
raise errors.WaitForResponseTimedOutError()
def WaitForBootComplete(self, wait_time=120):
diff --git a/testrunner/test_defs/test_walker.py b/testrunner/test_defs/test_walker.py
index 06c4e6d..4ef6923 100755
--- a/testrunner/test_defs/test_walker.py
+++ b/testrunner/test_defs/test_walker.py
@@ -116,7 +116,8 @@
Args:
path: absolute file system path to check
tests: current list of found tests
- build_path: the parent directory where Android.mk was found
+ build_path: the parent directory where Android.mk that builds sub-folders
+ was found
Returns:
updated list of tests
@@ -124,17 +125,31 @@
if not os.path.isdir(path):
return tests
filenames = os.listdir(path)
- # Try to build as much of original path as possible, so
- # keep track of upper-most parent directory where Android.mk was found
- # this is also necessary in case of overlapping tests
- # ie if a test exists at 'foo' directory and 'foo/sub', attempting to
- # build both 'foo' and 'foo/sub' will fail.
- if not build_path and filenames.count(android_mk.AndroidMK.FILENAME):
- build_path = self._MakePathRelativeToBuild(path)
if filenames.count(android_manifest.AndroidManifest.FILENAME):
# found a manifest! now parse it to find the test definition(s)
manifest = android_manifest.AndroidManifest(app_path=path)
- tests.extend(self._CreateSuitesFromManifest(manifest, build_path))
+ if not build_path:
+ # haven't found a parent makefile which builds this dir. Use current
+ # dir as build path
+ tests.extend(self._CreateSuitesFromManifest(
+ manifest, self._MakePathRelativeToBuild(path)))
+ else:
+ tests.extend(self._CreateSuitesFromManifest(manifest, build_path))
+ # Try to build as much of original path as possible, so
+ # keep track of upper-most parent directory where Android.mk was found that
+ # has rule to build sub-directory makefiles
+ # this is also necessary in case of overlapping tests
+ # ie if a test exists at 'foo' directory and 'foo/sub', attempting to
+ # build both 'foo' and 'foo/sub' will fail.
+ if filenames.count(android_mk.AndroidMK.FILENAME):
+ android_mk_parser = android_mk.AndroidMK(app_path=path)
+ if android_mk_parser.HasInclude('call all-makefiles-under,$(LOCAL_PATH)'):
+ # found rule to build sub-directories. The parent path can be used,
+ # or if not set, use current path
+ if not build_path:
+ build_path = self._MakePathRelativeToBuild(path)
+ else:
+ build_path = None
for filename in filenames:
self._FindSubTests(os.path.join(path, filename), tests, build_path)
return tests
diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/Android.mk b/tools/emulator/opengl/tests/EGL_host_wrapper/Android.mk
new file mode 100644
index 0000000..19d8794
--- /dev/null
+++ b/tools/emulator/opengl/tests/EGL_host_wrapper/Android.mk
@@ -0,0 +1,16 @@
+ifeq ($(HOST_OS),linux)
+
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-host-static-library,libEGL_host_wrapper)
+
+LOCAL_SRC_FILES := \
+ egl.cpp \
+ egl_dispatch.cpp
+
+$(call emugl-export,LDLIBS,-ldl -pthread)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+
+$(call emugl-end-module)
+
+endif # HOST_OS == linux
diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl.cpp b/tools/emulator/opengl/tests/EGL_host_wrapper/egl.cpp
new file mode 100644
index 0000000..6fa27ac
--- /dev/null
+++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl.cpp
@@ -0,0 +1,277 @@
+/*
+* 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "egl_dispatch.h"
+#include "egl_ftable.h"
+#include <pthread.h>
+
+#define EGL_LIB "ANDROID_EGL_LIB"
+
+static struct egl_dispatch *s_dispatch = NULL;
+static pthread_once_t eglDispatchInitialized = PTHREAD_ONCE_INIT;
+
+void initEglDispatch()
+{
+ //
+ // Load back-end EGL implementation library
+ //
+ char *eglLib = (char *) "libEGL.so";
+ if (getenv(EGL_LIB) != NULL) {
+ eglLib = getenv(EGL_LIB);
+ }
+
+ s_dispatch = loadEGL(eglLib);
+ if (!s_dispatch) {
+ fprintf(stderr,"FATAL ERROR: Could not load EGL lib [%s]\n", eglLib);
+ exit(-1);
+ }
+}
+
+static struct egl_dispatch *getDispatch()
+{
+ pthread_once(&eglDispatchInitialized, initEglDispatch);
+ return s_dispatch;
+}
+
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
+{
+ for (int i=0; i<egl_num_funcs; i++) {
+ if (!strcmp(egl_funcs_by_name[i].name, procname)) {
+ return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
+ }
+ }
+
+ return getDispatch()->eglGetProcAddress(procname);
+}
+
+//////////////// Path through functions //////////
+
+EGLint eglGetError()
+{
+ return getDispatch()->eglGetError();
+}
+
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
+{
+ return getDispatch()->eglGetDisplay(display_id);
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ return getDispatch()->eglInitialize(dpy, major, minor);
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+ return getDispatch()->eglTerminate(dpy);
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+ return getDispatch()->eglQueryString(dpy, name);
+}
+
+EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ return getDispatch()->eglGetConfigs(dpy, configs, config_size, num_config);
+}
+
+EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ return getDispatch()->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+ return getDispatch()->eglGetConfigAttrib(dpy, config, attribute, value);
+}
+
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreateWindowSurface(dpy, config, win, attrib_list);
+}
+
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreatePbufferSurface(dpy, config, attrib_list);
+}
+
+EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ return getDispatch()->eglDestroySurface(dpy, surface);
+}
+
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+ return getDispatch()->eglQuerySurface(dpy, surface, attribute, value);
+}
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+ return getDispatch()->eglBindAPI(api);
+}
+
+EGLenum eglQueryAPI()
+{
+ return getDispatch()->eglQueryAPI();
+}
+
+EGLBoolean eglWaitClient()
+{
+ return getDispatch()->eglWaitClient();
+}
+
+EGLBoolean eglReleaseThread()
+{
+ return getDispatch()->eglReleaseThread();
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+ return getDispatch()->eglSurfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ return getDispatch()->eglBindTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ return getDispatch()->eglReleaseTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ return getDispatch()->eglSwapInterval(dpy, interval);
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreateContext(dpy, config, share_context, attrib_list);
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ return getDispatch()->eglDestroyContext(dpy, ctx);
+}
+
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+ return getDispatch()->eglMakeCurrent(dpy, draw, read, ctx);
+}
+
+EGLContext eglGetCurrentContext()
+{
+ return getDispatch()->eglGetCurrentContext();
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+ return getDispatch()->eglGetCurrentSurface(readdraw);
+}
+
+EGLDisplay eglGetCurrentDisplay()
+{
+ return getDispatch()->eglGetCurrentDisplay();
+}
+
+EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+ return getDispatch()->eglQueryContext(dpy, ctx, attribute, value);
+}
+
+EGLBoolean eglWaitGL()
+{
+ return getDispatch()->eglWaitGL();
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+ return getDispatch()->eglWaitNative(engine);
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ return getDispatch()->eglSwapBuffers(dpy, surface);
+}
+
+EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+ return getDispatch()->eglCopyBuffers(dpy, surface, target);
+}
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
+{
+ return getDispatch()->eglLockSurfaceKHR(display, surface, attrib_list);
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
+{
+ return getDispatch()->eglUnlockSurfaceKHR(display, surface);
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+ return getDispatch()->eglDestroyImageKHR(dpy, image);
+}
+
+EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ return getDispatch()->eglDestroySyncKHR(dpy, sync);
+}
+
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+ return getDispatch()->eglClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+{
+ return getDispatch()->eglSignalSyncKHR(dpy, sync, mode);
+}
+
+EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+ return getDispatch()->eglGetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height)
+{
+ return getDispatch()->eglSetSwapRectangleANDROID(dpy, draw, left, top, width, height);
+}
diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.cpp b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.cpp
new file mode 100644
index 0000000..a9b8214
--- /dev/null
+++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.cpp
@@ -0,0 +1,77 @@
+/*
+* 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.
+*/
+#include <stdio.h>
+#include <dlfcn.h>
+#include "egl_dispatch.h"
+
+
+egl_dispatch *loadEGL(const char *p_eglPath)
+{
+ void *libEGL = dlopen(p_eglPath, RTLD_NOW);
+ if (!libEGL) {
+ return NULL;
+ }
+
+ egl_dispatch *disp = new egl_dispatch;
+
+ void *ptr;
+ ptr = dlsym(libEGL,"eglGetError"); disp->set_eglGetError((eglGetError_t)ptr);
+ ptr = dlsym(libEGL,"eglGetDisplay"); disp->set_eglGetDisplay((eglGetDisplay_t)ptr);
+ ptr = dlsym(libEGL,"eglInitialize"); disp->set_eglInitialize((eglInitialize_t)ptr);
+ ptr = dlsym(libEGL,"eglTerminate"); disp->set_eglTerminate((eglTerminate_t)ptr);
+ ptr = dlsym(libEGL,"eglQueryString"); disp->set_eglQueryString((eglQueryString_t)ptr);
+ ptr = dlsym(libEGL,"eglGetConfigs"); disp->set_eglGetConfigs((eglGetConfigs_t)ptr);
+ ptr = dlsym(libEGL,"eglChooseConfig"); disp->set_eglChooseConfig((eglChooseConfig_t)ptr);
+ ptr = dlsym(libEGL,"eglGetConfigAttrib"); disp->set_eglGetConfigAttrib((eglGetConfigAttrib_t)ptr);
+ ptr = dlsym(libEGL,"eglCreateWindowSurface"); disp->set_eglCreateWindowSurface((eglCreateWindowSurface_t)ptr);
+ ptr = dlsym(libEGL,"eglCreatePbufferSurface"); disp->set_eglCreatePbufferSurface((eglCreatePbufferSurface_t)ptr);
+ ptr = dlsym(libEGL,"eglCreatePixmapSurface"); disp->set_eglCreatePixmapSurface((eglCreatePixmapSurface_t)ptr);
+ ptr = dlsym(libEGL,"eglDestroySurface"); disp->set_eglDestroySurface((eglDestroySurface_t)ptr);
+ ptr = dlsym(libEGL,"eglQuerySurface"); disp->set_eglQuerySurface((eglQuerySurface_t)ptr);
+ ptr = dlsym(libEGL,"eglBindAPI"); disp->set_eglBindAPI((eglBindAPI_t)ptr);
+ ptr = dlsym(libEGL,"eglQueryAPI"); disp->set_eglQueryAPI((eglQueryAPI_t)ptr);
+ ptr = dlsym(libEGL,"eglWaitClient"); disp->set_eglWaitClient((eglWaitClient_t)ptr);
+ ptr = dlsym(libEGL,"eglReleaseThread"); disp->set_eglReleaseThread((eglReleaseThread_t)ptr);
+ ptr = dlsym(libEGL,"eglCreatePbufferFromClientBuffer"); disp->set_eglCreatePbufferFromClientBuffer((eglCreatePbufferFromClientBuffer_t)ptr);
+ ptr = dlsym(libEGL,"eglSurfaceAttrib"); disp->set_eglSurfaceAttrib((eglSurfaceAttrib_t)ptr);
+ ptr = dlsym(libEGL,"eglBindTexImage"); disp->set_eglBindTexImage((eglBindTexImage_t)ptr);
+ ptr = dlsym(libEGL,"eglReleaseTexImage"); disp->set_eglReleaseTexImage((eglReleaseTexImage_t)ptr);
+ ptr = dlsym(libEGL,"eglSwapInterval"); disp->set_eglSwapInterval((eglSwapInterval_t)ptr);
+ ptr = dlsym(libEGL,"eglCreateContext"); disp->set_eglCreateContext((eglCreateContext_t)ptr);
+ ptr = dlsym(libEGL,"eglDestroyContext"); disp->set_eglDestroyContext((eglDestroyContext_t)ptr);
+ ptr = dlsym(libEGL,"eglMakeCurrent"); disp->set_eglMakeCurrent((eglMakeCurrent_t)ptr);
+ ptr = dlsym(libEGL,"eglGetCurrentContext"); disp->set_eglGetCurrentContext((eglGetCurrentContext_t)ptr);
+ ptr = dlsym(libEGL,"eglGetCurrentSurface"); disp->set_eglGetCurrentSurface((eglGetCurrentSurface_t)ptr);
+ ptr = dlsym(libEGL,"eglGetCurrentDisplay"); disp->set_eglGetCurrentDisplay((eglGetCurrentDisplay_t)ptr);
+ ptr = dlsym(libEGL,"eglQueryContext"); disp->set_eglQueryContext((eglQueryContext_t)ptr);
+ ptr = dlsym(libEGL,"eglWaitGL"); disp->set_eglWaitGL((eglWaitGL_t)ptr);
+ ptr = dlsym(libEGL,"eglWaitNative"); disp->set_eglWaitNative((eglWaitNative_t)ptr);
+ ptr = dlsym(libEGL,"eglSwapBuffers"); disp->set_eglSwapBuffers((eglSwapBuffers_t)ptr);
+ ptr = dlsym(libEGL,"eglCopyBuffers"); disp->set_eglCopyBuffers((eglCopyBuffers_t)ptr);
+ ptr = dlsym(libEGL,"eglGetProcAddress"); disp->set_eglGetProcAddress((eglGetProcAddress_t)ptr);
+ ptr = dlsym(libEGL,"eglLockSurfaceKHR"); disp->set_eglLockSurfaceKHR((eglLockSurfaceKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglUnlockSurfaceKHR"); disp->set_eglUnlockSurfaceKHR((eglUnlockSurfaceKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglCreateImageKHR"); disp->set_eglCreateImageKHR((eglCreateImageKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglDestroyImageKHR"); disp->set_eglDestroyImageKHR((eglDestroyImageKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglCreateSyncKHR"); disp->set_eglCreateSyncKHR((eglCreateSyncKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglDestroySyncKHR"); disp->set_eglDestroySyncKHR((eglDestroySyncKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglClientWaitSyncKHR"); disp->set_eglClientWaitSyncKHR((eglClientWaitSyncKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglSignalSyncKHR"); disp->set_eglSignalSyncKHR((eglSignalSyncKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglGetSyncAttribKHR"); disp->set_eglGetSyncAttribKHR((eglGetSyncAttribKHR_t)ptr);
+ ptr = dlsym(libEGL,"eglSetSwapRectangleANDROID"); disp->set_eglSetSwapRectangleANDROID((eglSetSwapRectangleANDROID_t)ptr);
+
+ return disp;
+}
diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.h b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.h
new file mode 100644
index 0000000..e5f67c9
--- /dev/null
+++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.h
@@ -0,0 +1,115 @@
+/*
+* 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.
+*/
+#ifndef _EGL_DISPATCH_H
+#define _EGL_DISPATCH_H
+
+#include "egl_proc.h"
+
+struct egl_dispatch {
+ eglGetError_t eglGetError;
+ eglGetDisplay_t eglGetDisplay;
+ eglInitialize_t eglInitialize;
+ eglTerminate_t eglTerminate;
+ eglQueryString_t eglQueryString;
+ eglGetConfigs_t eglGetConfigs;
+ eglChooseConfig_t eglChooseConfig;
+ eglGetConfigAttrib_t eglGetConfigAttrib;
+ eglCreateWindowSurface_t eglCreateWindowSurface;
+ eglCreatePbufferSurface_t eglCreatePbufferSurface;
+ eglCreatePixmapSurface_t eglCreatePixmapSurface;
+ eglDestroySurface_t eglDestroySurface;
+ eglQuerySurface_t eglQuerySurface;
+ eglBindAPI_t eglBindAPI;
+ eglQueryAPI_t eglQueryAPI;
+ eglWaitClient_t eglWaitClient;
+ eglReleaseThread_t eglReleaseThread;
+ eglCreatePbufferFromClientBuffer_t eglCreatePbufferFromClientBuffer;
+ eglSurfaceAttrib_t eglSurfaceAttrib;
+ eglBindTexImage_t eglBindTexImage;
+ eglReleaseTexImage_t eglReleaseTexImage;
+ eglSwapInterval_t eglSwapInterval;
+ eglCreateContext_t eglCreateContext;
+ eglDestroyContext_t eglDestroyContext;
+ eglMakeCurrent_t eglMakeCurrent;
+ eglGetCurrentContext_t eglGetCurrentContext;
+ eglGetCurrentSurface_t eglGetCurrentSurface;
+ eglGetCurrentDisplay_t eglGetCurrentDisplay;
+ eglQueryContext_t eglQueryContext;
+ eglWaitGL_t eglWaitGL;
+ eglWaitNative_t eglWaitNative;
+ eglSwapBuffers_t eglSwapBuffers;
+ eglCopyBuffers_t eglCopyBuffers;
+ eglGetProcAddress_t eglGetProcAddress;
+ eglLockSurfaceKHR_t eglLockSurfaceKHR;
+ eglUnlockSurfaceKHR_t eglUnlockSurfaceKHR;
+ eglCreateImageKHR_t eglCreateImageKHR;
+ eglDestroyImageKHR_t eglDestroyImageKHR;
+ eglCreateSyncKHR_t eglCreateSyncKHR;
+ eglDestroySyncKHR_t eglDestroySyncKHR;
+ eglClientWaitSyncKHR_t eglClientWaitSyncKHR;
+ eglSignalSyncKHR_t eglSignalSyncKHR;
+ eglGetSyncAttribKHR_t eglGetSyncAttribKHR;
+ eglSetSwapRectangleANDROID_t eglSetSwapRectangleANDROID;
+ //Accessors
+ eglGetError_t set_eglGetError(eglGetError_t f) { eglGetError_t retval = eglGetError; eglGetError = f; return retval;}
+ eglGetDisplay_t set_eglGetDisplay(eglGetDisplay_t f) { eglGetDisplay_t retval = eglGetDisplay; eglGetDisplay = f; return retval;}
+ eglInitialize_t set_eglInitialize(eglInitialize_t f) { eglInitialize_t retval = eglInitialize; eglInitialize = f; return retval;}
+ eglTerminate_t set_eglTerminate(eglTerminate_t f) { eglTerminate_t retval = eglTerminate; eglTerminate = f; return retval;}
+ eglQueryString_t set_eglQueryString(eglQueryString_t f) { eglQueryString_t retval = eglQueryString; eglQueryString = f; return retval;}
+ eglGetConfigs_t set_eglGetConfigs(eglGetConfigs_t f) { eglGetConfigs_t retval = eglGetConfigs; eglGetConfigs = f; return retval;}
+ eglChooseConfig_t set_eglChooseConfig(eglChooseConfig_t f) { eglChooseConfig_t retval = eglChooseConfig; eglChooseConfig = f; return retval;}
+ eglGetConfigAttrib_t set_eglGetConfigAttrib(eglGetConfigAttrib_t f) { eglGetConfigAttrib_t retval = eglGetConfigAttrib; eglGetConfigAttrib = f; return retval;}
+ eglCreateWindowSurface_t set_eglCreateWindowSurface(eglCreateWindowSurface_t f) { eglCreateWindowSurface_t retval = eglCreateWindowSurface; eglCreateWindowSurface = f; return retval;}
+ eglCreatePbufferSurface_t set_eglCreatePbufferSurface(eglCreatePbufferSurface_t f) { eglCreatePbufferSurface_t retval = eglCreatePbufferSurface; eglCreatePbufferSurface = f; return retval;}
+ eglCreatePixmapSurface_t set_eglCreatePixmapSurface(eglCreatePixmapSurface_t f) { eglCreatePixmapSurface_t retval = eglCreatePixmapSurface; eglCreatePixmapSurface = f; return retval;}
+ eglDestroySurface_t set_eglDestroySurface(eglDestroySurface_t f) { eglDestroySurface_t retval = eglDestroySurface; eglDestroySurface = f; return retval;}
+ eglQuerySurface_t set_eglQuerySurface(eglQuerySurface_t f) { eglQuerySurface_t retval = eglQuerySurface; eglQuerySurface = f; return retval;}
+ eglBindAPI_t set_eglBindAPI(eglBindAPI_t f) { eglBindAPI_t retval = eglBindAPI; eglBindAPI = f; return retval;}
+ eglQueryAPI_t set_eglQueryAPI(eglQueryAPI_t f) { eglQueryAPI_t retval = eglQueryAPI; eglQueryAPI = f; return retval;}
+ eglWaitClient_t set_eglWaitClient(eglWaitClient_t f) { eglWaitClient_t retval = eglWaitClient; eglWaitClient = f; return retval;}
+ eglReleaseThread_t set_eglReleaseThread(eglReleaseThread_t f) { eglReleaseThread_t retval = eglReleaseThread; eglReleaseThread = f; return retval;}
+ eglCreatePbufferFromClientBuffer_t set_eglCreatePbufferFromClientBuffer(eglCreatePbufferFromClientBuffer_t f) { eglCreatePbufferFromClientBuffer_t retval = eglCreatePbufferFromClientBuffer; eglCreatePbufferFromClientBuffer = f; return retval;}
+ eglSurfaceAttrib_t set_eglSurfaceAttrib(eglSurfaceAttrib_t f) { eglSurfaceAttrib_t retval = eglSurfaceAttrib; eglSurfaceAttrib = f; return retval;}
+ eglBindTexImage_t set_eglBindTexImage(eglBindTexImage_t f) { eglBindTexImage_t retval = eglBindTexImage; eglBindTexImage = f; return retval;}
+ eglReleaseTexImage_t set_eglReleaseTexImage(eglReleaseTexImage_t f) { eglReleaseTexImage_t retval = eglReleaseTexImage; eglReleaseTexImage = f; return retval;}
+ eglSwapInterval_t set_eglSwapInterval(eglSwapInterval_t f) { eglSwapInterval_t retval = eglSwapInterval; eglSwapInterval = f; return retval;}
+ eglCreateContext_t set_eglCreateContext(eglCreateContext_t f) { eglCreateContext_t retval = eglCreateContext; eglCreateContext = f; return retval;}
+ eglDestroyContext_t set_eglDestroyContext(eglDestroyContext_t f) { eglDestroyContext_t retval = eglDestroyContext; eglDestroyContext = f; return retval;}
+ eglMakeCurrent_t set_eglMakeCurrent(eglMakeCurrent_t f) { eglMakeCurrent_t retval = eglMakeCurrent; eglMakeCurrent = f; return retval;}
+ eglGetCurrentContext_t set_eglGetCurrentContext(eglGetCurrentContext_t f) { eglGetCurrentContext_t retval = eglGetCurrentContext; eglGetCurrentContext = f; return retval;}
+ eglGetCurrentSurface_t set_eglGetCurrentSurface(eglGetCurrentSurface_t f) { eglGetCurrentSurface_t retval = eglGetCurrentSurface; eglGetCurrentSurface = f; return retval;}
+ eglGetCurrentDisplay_t set_eglGetCurrentDisplay(eglGetCurrentDisplay_t f) { eglGetCurrentDisplay_t retval = eglGetCurrentDisplay; eglGetCurrentDisplay = f; return retval;}
+ eglQueryContext_t set_eglQueryContext(eglQueryContext_t f) { eglQueryContext_t retval = eglQueryContext; eglQueryContext = f; return retval;}
+ eglWaitGL_t set_eglWaitGL(eglWaitGL_t f) { eglWaitGL_t retval = eglWaitGL; eglWaitGL = f; return retval;}
+ eglWaitNative_t set_eglWaitNative(eglWaitNative_t f) { eglWaitNative_t retval = eglWaitNative; eglWaitNative = f; return retval;}
+ eglSwapBuffers_t set_eglSwapBuffers(eglSwapBuffers_t f) { eglSwapBuffers_t retval = eglSwapBuffers; eglSwapBuffers = f; return retval;}
+ eglCopyBuffers_t set_eglCopyBuffers(eglCopyBuffers_t f) { eglCopyBuffers_t retval = eglCopyBuffers; eglCopyBuffers = f; return retval;}
+ eglGetProcAddress_t set_eglGetProcAddress(eglGetProcAddress_t f) { eglGetProcAddress_t retval = eglGetProcAddress; eglGetProcAddress = f; return retval;}
+ eglLockSurfaceKHR_t set_eglLockSurfaceKHR(eglLockSurfaceKHR_t f) { eglLockSurfaceKHR_t retval = eglLockSurfaceKHR; eglLockSurfaceKHR = f; return retval;}
+ eglUnlockSurfaceKHR_t set_eglUnlockSurfaceKHR(eglUnlockSurfaceKHR_t f) { eglUnlockSurfaceKHR_t retval = eglUnlockSurfaceKHR; eglUnlockSurfaceKHR = f; return retval;}
+ eglCreateImageKHR_t set_eglCreateImageKHR(eglCreateImageKHR_t f) { eglCreateImageKHR_t retval = eglCreateImageKHR; eglCreateImageKHR = f; return retval;}
+ eglDestroyImageKHR_t set_eglDestroyImageKHR(eglDestroyImageKHR_t f) { eglDestroyImageKHR_t retval = eglDestroyImageKHR; eglDestroyImageKHR = f; return retval;}
+ eglCreateSyncKHR_t set_eglCreateSyncKHR(eglCreateSyncKHR_t f) { eglCreateSyncKHR_t retval = eglCreateSyncKHR; eglCreateSyncKHR = f; return retval;}
+ eglDestroySyncKHR_t set_eglDestroySyncKHR(eglDestroySyncKHR_t f) { eglDestroySyncKHR_t retval = eglDestroySyncKHR; eglDestroySyncKHR = f; return retval;}
+ eglClientWaitSyncKHR_t set_eglClientWaitSyncKHR(eglClientWaitSyncKHR_t f) { eglClientWaitSyncKHR_t retval = eglClientWaitSyncKHR; eglClientWaitSyncKHR = f; return retval;}
+ eglSignalSyncKHR_t set_eglSignalSyncKHR(eglSignalSyncKHR_t f) { eglSignalSyncKHR_t retval = eglSignalSyncKHR; eglSignalSyncKHR = f; return retval;}
+ eglGetSyncAttribKHR_t set_eglGetSyncAttribKHR(eglGetSyncAttribKHR_t f) { eglGetSyncAttribKHR_t retval = eglGetSyncAttribKHR; eglGetSyncAttribKHR = f; return retval;}
+ eglSetSwapRectangleANDROID_t set_eglSetSwapRectangleANDROID(eglSetSwapRectangleANDROID_t f) { eglSetSwapRectangleANDROID_t retval = eglSetSwapRectangleANDROID; eglSetSwapRectangleANDROID = f; return retval;}
+};
+
+egl_dispatch *loadEGL(const char *p_eglPath);
+
+#endif
diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_ftable.h b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_ftable.h
new file mode 100644
index 0000000..ee40585
--- /dev/null
+++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_ftable.h
@@ -0,0 +1,66 @@
+/*
+* 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.
+*/
+static struct _egl_funcs_by_name {
+ const char *name;
+ void *proc;
+} egl_funcs_by_name[] = {
+ {"eglGetError", (void *)eglGetError},
+ {"eglGetDisplay", (void *)eglGetDisplay},
+ {"eglInitialize", (void *)eglInitialize},
+ {"eglTerminate", (void *)eglTerminate},
+ {"eglQueryString", (void *)eglQueryString},
+ {"eglGetConfigs", (void *)eglGetConfigs},
+ {"eglChooseConfig", (void *)eglChooseConfig},
+ {"eglGetConfigAttrib", (void *)eglGetConfigAttrib},
+ {"eglCreateWindowSurface", (void *)eglCreateWindowSurface},
+ {"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface},
+ {"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface},
+ {"eglDestroySurface", (void *)eglDestroySurface},
+ {"eglQuerySurface", (void *)eglQuerySurface},
+ {"eglBindAPI", (void *)eglBindAPI},
+ {"eglQueryAPI", (void *)eglQueryAPI},
+ {"eglWaitClient", (void *)eglWaitClient},
+ {"eglReleaseThread", (void *)eglReleaseThread},
+ {"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer},
+ {"eglSurfaceAttrib", (void *)eglSurfaceAttrib},
+ {"eglBindTexImage", (void *)eglBindTexImage},
+ {"eglReleaseTexImage", (void *)eglReleaseTexImage},
+ {"eglSwapInterval", (void *)eglSwapInterval},
+ {"eglCreateContext", (void *)eglCreateContext},
+ {"eglDestroyContext", (void *)eglDestroyContext},
+ {"eglMakeCurrent", (void *)eglMakeCurrent},
+ {"eglGetCurrentContext", (void *)eglGetCurrentContext},
+ {"eglGetCurrentSurface", (void *)eglGetCurrentSurface},
+ {"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay},
+ {"eglQueryContext", (void *)eglQueryContext},
+ {"eglWaitGL", (void *)eglWaitGL},
+ {"eglWaitNative", (void *)eglWaitNative},
+ {"eglSwapBuffers", (void *)eglSwapBuffers},
+ {"eglCopyBuffers", (void *)eglCopyBuffers},
+ {"eglGetProcAddress", (void *)eglGetProcAddress},
+ {"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR},
+ {"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR},
+ {"eglCreateImageKHR", (void *)eglCreateImageKHR},
+ {"eglDestroyImageKHR", (void *)eglDestroyImageKHR},
+ {"eglCreateSyncKHR", (void *)eglCreateSyncKHR},
+ {"eglDestroySyncKHR", (void *)eglDestroySyncKHR},
+ {"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR},
+ {"eglSignalSyncKHR", (void *)eglSignalSyncKHR},
+ {"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR},
+ {"eglSetSwapRectangleANDROID", (void *)eglSetSwapRectangleANDROID}
+};
+
+static int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);
diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_proc.h b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_proc.h
new file mode 100644
index 0000000..140c030
--- /dev/null
+++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_proc.h
@@ -0,0 +1,68 @@
+/*
+* 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.
+*/
+#ifndef _EGL_PROC_H
+#define _EGL_PROC_H
+
+#include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+
+typedef EGLint (* eglGetError_t) ();
+typedef EGLDisplay (* eglGetDisplay_t) (EGLNativeDisplayType);
+typedef EGLBoolean (* eglInitialize_t) (EGLDisplay, EGLint*, EGLint*);
+typedef EGLBoolean (* eglTerminate_t) (EGLDisplay);
+typedef char* (* eglQueryString_t) (EGLDisplay, EGLint);
+typedef EGLBoolean (* eglGetConfigs_t) (EGLDisplay, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglChooseConfig_t) (EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglGetConfigAttrib_t) (EGLDisplay, EGLConfig, EGLint, EGLint*);
+typedef EGLSurface (* eglCreateWindowSurface_t) (EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint*);
+typedef EGLSurface (* eglCreatePbufferSurface_t) (EGLDisplay, EGLConfig, const EGLint*);
+typedef EGLSurface (* eglCreatePixmapSurface_t) (EGLDisplay, EGLConfig, EGLNativePixmapType, const EGLint*);
+typedef EGLBoolean (* eglDestroySurface_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglQuerySurface_t) (EGLDisplay, EGLSurface, EGLint, EGLint*);
+typedef EGLBoolean (* eglBindAPI_t) (EGLenum);
+typedef EGLenum (* eglQueryAPI_t) ();
+typedef EGLBoolean (* eglWaitClient_t) ();
+typedef EGLBoolean (* eglReleaseThread_t) ();
+typedef EGLSurface (* eglCreatePbufferFromClientBuffer_t) (EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint*);
+typedef EGLBoolean (* eglSurfaceAttrib_t) (EGLDisplay, EGLSurface, EGLint, EGLint);
+typedef EGLBoolean (* eglBindTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglReleaseTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglSwapInterval_t) (EGLDisplay, EGLint);
+typedef EGLContext (* eglCreateContext_t) (EGLDisplay, EGLConfig, EGLContext, const EGLint*);
+typedef EGLBoolean (* eglDestroyContext_t) (EGLDisplay, EGLContext);
+typedef EGLBoolean (* eglMakeCurrent_t) (EGLDisplay, EGLSurface, EGLSurface, EGLContext);
+typedef EGLContext (* eglGetCurrentContext_t) ();
+typedef EGLSurface (* eglGetCurrentSurface_t) (EGLint);
+typedef EGLDisplay (* eglGetCurrentDisplay_t) ();
+typedef EGLBoolean (* eglQueryContext_t) (EGLDisplay, EGLContext, EGLint, EGLint*);
+typedef EGLBoolean (* eglWaitGL_t) ();
+typedef EGLBoolean (* eglWaitNative_t) (EGLint);
+typedef EGLBoolean (* eglSwapBuffers_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglCopyBuffers_t) (EGLDisplay, EGLSurface, EGLNativePixmapType);
+typedef __eglMustCastToProperFunctionPointerType (* eglGetProcAddress_t) (const char*);
+typedef EGLBoolean (* eglLockSurfaceKHR_t) (EGLDisplay, EGLSurface, const EGLint*);
+typedef EGLBoolean (* eglUnlockSurfaceKHR_t) (EGLDisplay, EGLSurface);
+typedef EGLImageKHR (* eglCreateImageKHR_t) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
+typedef EGLBoolean (* eglDestroyImageKHR_t) (EGLDisplay, EGLImageKHR image);
+typedef EGLSyncKHR (* eglCreateSyncKHR_t) (EGLDisplay, EGLenum, const EGLint*);
+typedef EGLBoolean (* eglDestroySyncKHR_t) (EGLDisplay, EGLSyncKHR sync);
+typedef EGLint (* eglClientWaitSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR timeout);
+typedef EGLBoolean (* eglSignalSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLenum);
+typedef EGLBoolean (* eglGetSyncAttribKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLint*);
+typedef EGLBoolean (* eglSetSwapRectangleANDROID_t) (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
+
+#endif // of _EGL_PROC_H
diff --git a/tools/emulator/opengl/tests/emulator_test_renderer/Android.mk b/tools/emulator/opengl/tests/emulator_test_renderer/Android.mk
new file mode 100644
index 0000000..52a1c8e
--- /dev/null
+++ b/tools/emulator/opengl/tests/emulator_test_renderer/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH:=$(call my-dir)
+
+$(call emugl-begin-host-executable,emulator_test_renderer)
+$(call emugl-import,libOpenglRender event_injector)
+
+LOCAL_SRC_FILES := main.cpp
+
+PREBUILT := $(HOST_PREBUILT_TAG)
+LOCAL_SDL_CONFIG ?= prebuilt/$(PREBUILT)/sdl/bin/sdl-config
+LOCAL_SDL_CFLAGS := $(shell $(LOCAL_SDL_CONFIG) --cflags)
+LOCAL_SDL_LDLIBS := $(filter-out %.a %.lib,$(shell $(LOCAL_SDL_CONFIG) --static-libs))
+
+LOCAL_CFLAGS += $(LOCAL_SDL_CFLAGS) -g -O0
+LOCAL_LDLIBS += $(LOCAL_SDL_LDLIBS)
+
+ifeq ($(HOST_OS),windows)
+LOCAL_LDLIBS += -lws2_32
+endif
+
+LOCAL_STATIC_LIBRARIES += libSDL libSDLmain
+
+$(call emugl-end-module)
diff --git a/tools/emulator/opengl/tests/emulator_test_renderer/main.cpp b/tools/emulator/opengl/tests/emulator_test_renderer/main.cpp
new file mode 100644
index 0000000..06abce7
--- /dev/null
+++ b/tools/emulator/opengl/tests/emulator_test_renderer/main.cpp
@@ -0,0 +1,222 @@
+/*
+* 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.
+*/
+#undef HAVE_MALLOC_H
+#include <SDL.h>
+#include <SDL_syswm.h>
+#include <stdio.h>
+#include <string.h>
+#include "libOpenglRender/render_api.h"
+#include <EventInjector.h>
+
+static int convert_keysym(int sym); // forward
+
+#ifdef __linux__
+#include <X11/Xlib.h>
+#endif
+#ifdef _WIN32
+
+#include <winsock2.h>
+int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
+#else
+int main(int argc, char *argv[])
+#endif
+{
+ int portNum = 22468;
+ int winWidth = 320;
+ int winHeight = 480;
+ int width, height;
+ int mouseDown = 0;
+ const char* env = getenv("ANDROID_WINDOW_SIZE");
+ FBNativeWindowType windowId = NULL;
+ EventInjector* injector;
+ int consolePort = 5554;
+
+ if (env && sscanf(env, "%dx%d", &width, &height) == 2) {
+ winWidth = width;
+ winHeight = height;
+ }
+
+#ifdef __linux__
+ // some OpenGL implementations may call X functions
+ // it is safer to synchronize all X calls made by all the
+ // rendering threads. (although the calls we do are locked
+ // in the FrameBuffer singleton object).
+ XInitThreads();
+#endif
+
+ //
+ // Inialize SDL window
+ //
+ if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_VIDEO)) {
+ fprintf(stderr,"SDL init failed: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ SDL_Surface *surface = SDL_SetVideoMode(winWidth, winHeight, 32, SDL_SWSURFACE);
+ if (surface == NULL) {
+ fprintf(stderr,"Failed to set video mode: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ SDL_SysWMinfo wminfo;
+ memset(&wminfo, 0, sizeof(wminfo));
+ SDL_GetWMInfo(&wminfo);
+#ifdef _WIN32
+ windowId = wminfo.window;
+ WSADATA wsaData;
+ int rc = WSAStartup( MAKEWORD(2,2), &wsaData);
+ if (rc != 0) {
+ printf( "could not initialize Winsock\n" );
+ }
+#elif __linux__
+ windowId = wminfo.info.x11.window;
+#elif __APPLE__
+ windowId = wminfo.nsWindowPtr;
+#endif
+
+ printf("initializing renderer process\n");
+
+ //
+ // initialize OpenGL renderer to render in our window
+ //
+ bool inited = initOpenGLRenderer(winWidth, winHeight, portNum);
+ if (!inited) {
+ return -1;
+ }
+ printf("renderer process started\n");
+
+ float zRot = 0.0f;
+ inited = createOpenGLSubwindow(windowId, 0, 0,
+ winWidth, winHeight, zRot);
+ if (!inited) {
+ printf("failed to create OpenGL subwindow\n");
+ stopOpenGLRenderer();
+ return -1;
+ }
+ int subwinWidth = winWidth;
+ int subwinHeight = winHeight;
+
+ injector = new EventInjector(consolePort);
+
+ // Just wait until the window is closed
+ SDL_Event ev;
+
+ for (;;) {
+ injector->wait(1000/15);
+ injector->poll();
+
+ while (SDL_PollEvent(&ev)) {
+ switch (ev.type) {
+ case SDL_MOUSEBUTTONDOWN:
+ if (!mouseDown) {
+ injector->sendMouseDown(ev.button.x, ev.button.y);
+ mouseDown = 1;
+ }
+ break;
+ case SDL_MOUSEBUTTONUP:
+ if (mouseDown) {
+ injector->sendMouseUp(ev.button.x,ev.button.y);
+ mouseDown = 0;
+ }
+ break;
+ case SDL_MOUSEMOTION:
+ if (mouseDown)
+ injector->sendMouseMotion(ev.button.x,ev.button.y);
+ break;
+
+ case SDL_KEYDOWN:
+#ifdef __APPLE__
+ /* special code to deal with Command-Q properly */
+ if (ev.key.keysym.sym == SDLK_q &&
+ ev.key.keysym.mod & KMOD_META) {
+ goto EXIT;
+ }
+#endif
+ injector->sendKeyDown(convert_keysym(ev.key.keysym.sym));
+
+ if (ev.key.keysym.sym == SDLK_KP_MINUS) {
+ subwinWidth /= 2;
+ subwinHeight /= 2;
+
+ bool stat = destroyOpenGLSubwindow();
+ printf("destroy subwin returned %d\n", stat);
+ stat = createOpenGLSubwindow(windowId,
+ (winWidth - subwinWidth) / 2,
+ (winHeight - subwinHeight) / 2,
+ subwinWidth, subwinHeight,
+ zRot);
+ printf("create subwin returned %d\n", stat);
+ }
+ else if (ev.key.keysym.sym == SDLK_KP_PLUS) {
+ subwinWidth *= 2;
+ subwinHeight *= 2;
+
+ bool stat = destroyOpenGLSubwindow();
+ printf("destroy subwin returned %d\n", stat);
+ stat = createOpenGLSubwindow(windowId,
+ (winWidth - subwinWidth) / 2,
+ (winHeight - subwinHeight) / 2,
+ subwinWidth, subwinHeight,
+ zRot);
+ printf("create subwin returned %d\n", stat);
+ }
+ else if (ev.key.keysym.sym == SDLK_KP_MULTIPLY) {
+ zRot += 10.0f;
+ setOpenGLDisplayRotation(zRot);
+ }
+ else if (ev.key.keysym.sym == SDLK_KP_ENTER) {
+ repaintOpenGLDisplay();
+ }
+ break;
+ case SDL_KEYUP:
+ injector->sendKeyUp(convert_keysym(ev.key.keysym.sym));
+ break;
+ case SDL_QUIT:
+ goto EXIT;
+ }
+ }
+ }
+EXIT:
+ //
+ // stop the renderer
+ //
+ printf("stopping the renderer process\n");
+ stopOpenGLRenderer();
+
+ return 0;
+}
+
+static int convert_keysym(int sym)
+{
+#define EE(x,y) SDLK_##x, EventInjector::KEY_##y,
+ static const int keymap[] = {
+ EE(LEFT,LEFT)
+ EE(RIGHT,RIGHT)
+ EE(DOWN,DOWN)
+ EE(UP,UP)
+ EE(RETURN,ENTER)
+ EE(F1,SOFT1)
+ EE(ESCAPE,BACK)
+ EE(HOME,HOME)
+ -1
+ };
+ int nn;
+ for (nn = 0; keymap[nn] >= 0; nn += 2) {
+ if (keymap[nn] == sym)
+ return keymap[nn+1];
+ }
+ return sym;
+}
diff --git a/tools/emulator/opengl/tests/event_injector/Android.mk b/tools/emulator/opengl/tests/event_injector/Android.mk
new file mode 100644
index 0000000..26eb476
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-host-static-library,event_injector)
+
+LOCAL_SRC_FILES := \
+ EventInjector.cpp \
+ sockets.c \
+ emulator-console.c \
+ iolooper-select.c
+
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+
+$(call emugl-end-module)
diff --git a/tools/emulator/opengl/tests/event_injector/EventInjector.cpp b/tools/emulator/opengl/tests/event_injector/EventInjector.cpp
new file mode 100644
index 0000000..6dade6e
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/EventInjector.cpp
@@ -0,0 +1,76 @@
+/*
+* 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.
+*/
+#include "EventInjector.h"
+#include "emulator-console.h"
+
+#define PRIVATE EventInjectorPrivate
+
+class PRIVATE
+{
+public:
+ IoLooper* mLooper;
+ EmulatorConsole* mConsole;
+
+ EventInjectorPrivate(int port) {
+ mLooper = iolooper_new();
+ mConsole = emulatorConsole_new(port, mLooper);
+ }
+};
+
+EventInjector::EventInjector(int consolePort)
+{
+ mPrivate = new PRIVATE(consolePort);
+}
+
+EventInjector::~EventInjector()
+{
+ delete mPrivate;
+}
+
+void EventInjector::wait(int timeout_ms)
+{
+ iolooper_wait(mPrivate->mLooper, timeout_ms);
+}
+
+void EventInjector::poll(void)
+{
+ emulatorConsole_poll(mPrivate->mConsole);
+}
+
+void EventInjector::sendMouseDown( int x, int y )
+{
+ emulatorConsole_sendMouseDown(mPrivate->mConsole, x, y);
+}
+
+void EventInjector::sendMouseUp( int x, int y )
+{
+ emulatorConsole_sendMouseUp(mPrivate->mConsole, x, y);
+}
+
+void EventInjector::sendMouseMotion( int x, int y )
+{
+ emulatorConsole_sendMouseMotion(mPrivate->mConsole, x, y);
+}
+
+void EventInjector::sendKeyDown( int keycode )
+{
+ emulatorConsole_sendKey(mPrivate->mConsole, keycode, 1);
+}
+
+void EventInjector::sendKeyUp( int keycode )
+{
+ emulatorConsole_sendKey(mPrivate->mConsole, keycode, 0);
+}
diff --git a/tools/emulator/opengl/tests/event_injector/EventInjector.h b/tools/emulator/opengl/tests/event_injector/EventInjector.h
new file mode 100644
index 0000000..a8fded7
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/EventInjector.h
@@ -0,0 +1,59 @@
+/*
+* 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.
+*/
+/* Event redirector is used to inject user events from a GL window
+ * into the emulated program.
+ */
+#ifndef EVENT_INJECTOR_H
+#define EVENT_INJECTOR_H
+
+class EventInjectorPrivate;
+
+class EventInjector
+{
+public:
+ EventInjector(int consolePort);
+ virtual ~EventInjector();
+
+ void wait( int timeout_ms );
+ void poll( void );
+
+ void sendMouseDown( int x, int y );
+ void sendMouseUp( int x, int y );
+ void sendMouseMotion( int x, int y );
+ void sendKeyDown( int keycode );
+ void sendKeyUp( int keycode );
+
+ /* Keycode values expected by the Linux kernel, and the emulator */
+ enum {
+ KEY_BACK = 158,
+ KEY_HOME = 102,
+ KEY_SOFT1 = 229,
+ KEY_LEFT = 105,
+ KEY_UP = 103,
+ KEY_DOWN = 108,
+ KEY_RIGHT = 106,
+ KEY_VOLUMEUP = 115,
+ KEY_VOLUMEDOWN = 114,
+ KEY_SEND = 231,
+ KEY_END = 107,
+ KEY_ENTER = 28,
+ };
+
+private:
+ EventInjectorPrivate* mPrivate;
+};
+
+#endif /* EVENT_INJECTOR_H */
diff --git a/tools/emulator/opengl/tests/event_injector/emulator-console.c b/tools/emulator/opengl/tests/event_injector/emulator-console.c
new file mode 100644
index 0000000..a8c49b2
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/emulator-console.c
@@ -0,0 +1,345 @@
+/*
+* 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.
+*/
+#include "emulator-console.h"
+#include "sockets.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define DEBUG 0
+#if DEBUG >= 1
+# define D(...) printf(__VA_ARGS__), printf("\n")
+#else
+# define D(...) ((void)0)
+#endif
+#if DEBUG >= 2
+# define DD(...) printf(__VA_ARGS__), printf("\n")
+#else
+# define DD(...) ((void)0)
+#endif
+
+#define ANEW0(p) (p) = calloc(sizeof(*(p)), 1)
+
+enum {
+ STATE_CONNECTING = 0,
+ STATE_CONNECTED,
+ STATE_WAITING,
+ STATE_ERROR = 2
+};
+
+typedef struct Msg {
+ const char* data; // pointer to data
+ int size; // size of data
+ int sent; // already sent (so sent..size remain in buffer).
+ struct Msg* next; // next message in queue.
+} Msg;
+
+static Msg*
+msg_alloc( const char* data, int datalen )
+{
+ Msg* msg;
+
+ msg = malloc(sizeof(*msg) + datalen);
+ msg->data = (const char*)(msg + 1);
+ msg->size = datalen;
+ msg->sent = 0;
+ memcpy((char*)msg->data, data, datalen);
+ msg->next = NULL;
+
+ return msg;
+}
+
+static void
+msg_free( Msg* msg )
+{
+ free(msg);
+}
+
+struct EmulatorConsole {
+ int fd;
+ IoLooper* looper;
+ int state;
+ Msg* out_msg;
+ SockAddress address;
+ int64_t waitUntil;
+};
+
+/* Read as much from the input as possible, ignoring it.
+ */
+static int
+emulatorConsole_eatInput( EmulatorConsole* con )
+{
+ for (;;) {
+ char temp[64];
+ int ret = socket_recv(con->fd, temp, sizeof temp);
+ if (ret < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ return 0;
+ }
+ return -1;
+ }
+ if (ret == 0) {
+ return -1;
+ }
+ DD("Console received: '%.*s'", ret, temp);
+ }
+}
+
+static int
+emulatorConsole_sendOutput( EmulatorConsole* con )
+{
+ if (con->state != STATE_CONNECTED) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ while (con->out_msg != NULL) {
+ Msg* msg = con->out_msg;
+ int ret;
+
+ ret = socket_send(con->fd,
+ msg->data + msg->sent,
+ msg->size - msg->sent);
+ if (ret > 0) {
+ DD("Console sent: '%.*s'", ret, msg->data + msg->sent);
+
+ msg->sent += ret;
+ if (msg->sent == msg->size) {
+ con->out_msg = msg->next;
+ msg_free(msg);
+ }
+ continue;
+ }
+ if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ return 0;
+ }
+ con->state = STATE_ERROR;
+ D("Console error when sending: %s", strerror(errno));
+ return -1;
+ }
+ iolooper_del_write(con->looper, con->fd);
+ return 0;
+}
+
+static void
+emulatorConsole_completeConnect(EmulatorConsole* con)
+{
+ D("Console connected!");
+ iolooper_add_read(con->looper, con->fd);
+ iolooper_del_write(con->looper, con->fd);
+ con->state = STATE_CONNECTED;
+ if (con->out_msg != NULL) {
+ iolooper_add_write(con->looper, con->fd);
+ emulatorConsole_sendOutput(con);
+ }
+}
+
+static void
+emulatorConsole_retry(EmulatorConsole* con)
+{
+ /* Not possible yet, wait one second */
+ D("Could not connect to emulator, waiting 1 second: %s", errno_str);
+ con->state = STATE_WAITING;
+ con->waitUntil = iolooper_now() + 5000;
+}
+
+static void
+emulatorConsole_connect(EmulatorConsole* con)
+{
+ D("Trying to connect!");
+ if (con->fd < 0) {
+ con->fd = socket_create_inet( SOCKET_STREAM );
+ if (con->fd < 0) {
+ D("ERROR: Could not create socket: %s", errno_str);
+ con->state = STATE_ERROR;
+ return;
+ }
+ socket_set_nonblock(con->fd);
+ }
+ con->state = STATE_CONNECTING;
+ if (socket_connect(con->fd, &con->address) < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
+ iolooper_add_write(con->looper, con->fd);
+ } else {
+ emulatorConsole_retry(con);
+ }
+ return;
+ }
+
+ emulatorConsole_completeConnect(con);
+}
+
+static void
+emulatorConsole_reset( EmulatorConsole* con )
+{
+ D("Resetting console connection");
+ while (con->out_msg) {
+ Msg* msg = con->out_msg;
+ con->out_msg = msg->next;
+ msg_free(msg);
+ }
+ iolooper_del_read(con->looper, con->fd);
+ iolooper_del_write(con->looper, con->fd);
+ socket_close(con->fd);
+ con->fd = -1;
+ emulatorConsole_connect(con);
+}
+
+/* Create a new EmulatorConsole object to connect asynchronously to
+ * a given emulator port. Note that this should always succeeds since
+ * the connection is asynchronous.
+ */
+EmulatorConsole*
+emulatorConsole_new(int port, IoLooper* looper)
+{
+ EmulatorConsole* con;
+ SockAddress addr;
+
+ ANEW0(con);
+ con->looper = looper;
+ con->fd = -1;
+ sock_address_init_inet(&con->address, SOCK_ADDRESS_INET_LOOPBACK, port);
+
+ emulatorConsole_connect(con);
+ return con;
+}
+
+int
+emulatorConsole_poll( EmulatorConsole* con )
+{
+ int ret;
+
+ if (con->state == STATE_WAITING) {
+ if (iolooper_now() >= con->waitUntil)
+ emulatorConsole_connect(con);
+ return 0;
+ }
+
+ if (!iolooper_is_read(con->looper, con->fd) &&
+ !iolooper_is_write(con->looper, con->fd))
+ {
+ return 0;
+ }
+
+LOOP:
+ switch (con->state) {
+ case STATE_ERROR:
+ return -1;
+
+ case STATE_CONNECTING:
+ // read socket error to determine success / error.
+ if (socket_get_error(con->fd) != 0) {
+ emulatorConsole_retry(con);
+ } else {
+ emulatorConsole_completeConnect(con);
+ }
+ return 0;
+
+ case STATE_CONNECTED:
+ /* ignore input, if any */
+ if (iolooper_is_read(con->looper, con->fd)) {
+ if (emulatorConsole_eatInput(con) < 0) {
+ goto SET_ERROR;
+ }
+ }
+ /* send outgoing data, if any */
+ if (iolooper_is_write(con->looper, con->fd)) {
+ if (emulatorConsole_sendOutput(con) < 0) {
+ goto SET_ERROR;
+ }
+ }
+ return 0;
+
+ default:
+ D("UNSUPPORTED STATE!");
+ break;
+ }
+
+SET_ERROR:
+ D("Console ERROR!: %s\n", errno_str);
+ con->state = STATE_ERROR;
+ emulatorConsole_reset(con);
+ return -1;
+}
+
+/* Send a message to the console asynchronously. Any answer will be
+ * ignored. */
+void
+emulatorConsole_send( EmulatorConsole* con, const char* command )
+{
+ int cmdlen = strlen(command);
+ Msg* msg;
+ Msg** plast;
+
+ if (cmdlen == 0)
+ return;
+
+ /* Append new message at end of outgoing list */
+ msg = msg_alloc(command, cmdlen);
+ plast = &con->out_msg;
+ while (*plast) {
+ plast = &(*plast)->next;
+ }
+ *plast = msg;
+ if (con->out_msg == msg) {
+ iolooper_add_write(con->looper, con->fd);
+ }
+ emulatorConsole_sendOutput(con);
+}
+
+
+void
+emulatorConsole_sendMouseDown( EmulatorConsole* con, int x, int y )
+{
+ char temp[128];
+
+ D("sendMouseDown(%d,%d)", x, y);
+ snprintf(temp, sizeof temp,
+ "event send 3:0:%d 3:1:%d 1:330:1 0:0:0\r\n",
+ x, y);
+ emulatorConsole_send(con, temp);
+}
+
+void
+emulatorConsole_sendMouseMotion( EmulatorConsole* con, int x, int y )
+{
+ /* Same as mouse down */
+ emulatorConsole_sendMouseDown(con, x, y);
+}
+
+void
+emulatorConsole_sendMouseUp( EmulatorConsole* con, int x, int y )
+{
+ char temp[128];
+
+ D("sendMouseUp(%d,%d)", x, y);
+ snprintf(temp, sizeof temp,
+ "event send 3:0:%d 3:1:%d 1:330:0 0:0:0\r\n",
+ x, y);
+ emulatorConsole_send(con, temp);
+}
+
+#define EE(x,y) if (keycode == x) return y;
+
+void
+emulatorConsole_sendKey( EmulatorConsole* con, int keycode, int down )
+{
+ char temp[128];
+
+ snprintf(temp, sizeof temp,
+ "event send EV_KEY:%d:%d 0:0:0\r\n", keycode, down);
+ emulatorConsole_send(con, temp);
+}
diff --git a/tools/emulator/opengl/tests/event_injector/emulator-console.h b/tools/emulator/opengl/tests/event_injector/emulator-console.h
new file mode 100644
index 0000000..19e9687
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/emulator-console.h
@@ -0,0 +1,55 @@
+/*
+* 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.
+*/
+#ifndef ANDROID_EMULATOR_CONSOLE_H
+#define ANDROID_EMULATOR_CONSOLE_H
+
+#include "iolooper.h"
+#include "sockets.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmulatorConsole EmulatorConsole;
+
+/* Create a new EmulatorConsole object to connect asynchronously to
+ * a given emulator port. Note that this always succeeds since the
+ * connection is asynchronous.
+ */
+EmulatorConsole* emulatorConsole_new(int port, IoLooper* looper);
+
+/* Call this after an iolooper_poll() or iolooper_wait() to check
+ * the status of the console's socket and act upon it.
+ *
+ * Returns 0 on success, or -1 on error (which indicates disconnection!)
+ */
+int emulatorConsole_poll( EmulatorConsole* console );
+
+/* Send a message to the console asynchronously. Any answer will be
+ * ignored. */
+void emulatorConsole_send( EmulatorConsole* console, const char* command );
+
+void emulatorConsole_sendMouseDown( EmulatorConsole* con, int x, int y );
+void emulatorConsole_sendMouseMotion( EmulatorConsole* con, int x, int y );
+void emulatorConsole_sendMouseUp( EmulatorConsole* con, int x, int y );
+
+void emulatorConsole_sendKey( EmulatorConsole* con, int keycode, int down );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ANDROID_EMULATOR_CONSOLE_H */
diff --git a/tools/emulator/opengl/tests/event_injector/iolooper-select.c b/tools/emulator/opengl/tests/event_injector/iolooper-select.c
new file mode 100644
index 0000000..c5fc7c2
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/iolooper-select.c
@@ -0,0 +1,274 @@
+/*
+* 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.
+*/
+#include <errno.h>
+#include <stdlib.h>
+#include "iolooper.h"
+#include "sockets.h"
+
+/* An implementation of iolooper.h based on Unix select() */
+#ifdef _WIN32
+# include <winsock2.h>
+# include <time.h>
+#else
+# include <sys/types.h>
+# include <sys/select.h>
+# include <sys/time.h>
+#endif
+
+struct IoLooper {
+ fd_set reads[1];
+ fd_set writes[1];
+ fd_set reads_result[1];
+ fd_set writes_result[1];
+ int max_fd;
+ int max_fd_valid;
+};
+
+IoLooper*
+iolooper_new(void)
+{
+ IoLooper* iol = malloc(sizeof(*iol));
+ iolooper_reset(iol);
+ return iol;
+}
+
+void
+iolooper_free( IoLooper* iol )
+{
+ free(iol);
+}
+
+void
+iolooper_reset( IoLooper* iol )
+{
+ FD_ZERO(iol->reads);
+ FD_ZERO(iol->writes);
+ iol->max_fd = -1;
+ iol->max_fd_valid = 1;
+}
+
+static void
+iolooper_add_fd( IoLooper* iol, int fd )
+{
+ if (iol->max_fd_valid && fd > iol->max_fd) {
+ iol->max_fd = fd;
+ }
+}
+
+static void
+iolooper_del_fd( IoLooper* iol, int fd )
+{
+ if (iol->max_fd_valid && fd == iol->max_fd)
+ iol->max_fd_valid = 0;
+}
+
+void
+iolooper_modify( IoLooper* iol, int fd, int oldflags, int newflags )
+{
+ if (fd < 0)
+ return;
+
+ int changed = oldflags ^ newflags;
+
+ if ((changed & IOLOOPER_READ) != 0) {
+ if ((newflags & IOLOOPER_READ) != 0)
+ iolooper_add_read(iol, fd);
+ else
+ iolooper_del_read(iol, fd);
+ }
+ if ((changed & IOLOOPER_WRITE) != 0) {
+ if ((newflags & IOLOOPER_WRITE) != 0)
+ iolooper_add_write(iol, fd);
+ else
+ iolooper_del_write(iol, fd);
+ }
+}
+
+
+static int
+iolooper_fd_count( IoLooper* iol )
+{
+ int max_fd = iol->max_fd;
+ int fd;
+
+ if (iol->max_fd_valid)
+ return max_fd + 1;
+
+ /* recompute max fd */
+ for (fd = 0; fd < FD_SETSIZE; fd++) {
+ if (!FD_ISSET(fd, iol->reads) && !FD_ISSET(fd, iol->writes))
+ continue;
+
+ max_fd = fd;
+ }
+ iol->max_fd = max_fd;
+ iol->max_fd_valid = 1;
+
+ return max_fd + 1;
+}
+
+void
+iolooper_add_read( IoLooper* iol, int fd )
+{
+ if (fd >= 0) {
+ iolooper_add_fd(iol, fd);
+ FD_SET(fd, iol->reads);
+ }
+}
+
+void
+iolooper_add_write( IoLooper* iol, int fd )
+{
+ if (fd >= 0) {
+ iolooper_add_fd(iol, fd);
+ FD_SET(fd, iol->writes);
+ }
+}
+
+void
+iolooper_del_read( IoLooper* iol, int fd )
+{
+ if (fd >= 0) {
+ iolooper_del_fd(iol, fd);
+ FD_CLR(fd, iol->reads);
+ }
+}
+
+void
+iolooper_del_write( IoLooper* iol, int fd )
+{
+ if (fd >= 0) {
+ iolooper_del_fd(iol, fd);
+ FD_CLR(fd, iol->writes);
+ }
+}
+
+int
+iolooper_poll( IoLooper* iol )
+{
+ int count = iolooper_fd_count(iol);
+ int ret;
+ fd_set errs;
+
+ if (count == 0)
+ return 0;
+
+ FD_ZERO(&errs);
+
+ do {
+ struct timeval tv;
+
+ tv.tv_sec = tv.tv_usec = 0;
+
+ iol->reads_result[0] = iol->reads[0];
+ iol->writes_result[0] = iol->writes[0];
+
+ ret = select( count, iol->reads_result, iol->writes_result, &errs, &tv);
+ } while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
+int
+iolooper_wait( IoLooper* iol, int64_t duration )
+{
+ int count = iolooper_fd_count(iol);
+ int ret;
+ fd_set errs;
+ struct timeval tm0, *tm = NULL;
+
+ if (count == 0)
+ return 0;
+
+ if (duration < 0)
+ tm = NULL;
+ else {
+ tm = &tm0;
+ tm->tv_sec = duration / 1000;
+ tm->tv_usec = (duration - 1000*tm->tv_sec) * 1000;
+ }
+
+ FD_ZERO(&errs);
+
+ do {
+ iol->reads_result[0] = iol->reads[0];
+ iol->writes_result[0] = iol->writes[0];
+
+ ret = select( count, iol->reads_result, iol->writes_result, &errs, tm);
+ if (ret == 0) {
+ // Indicates timeout
+ errno = ETIMEDOUT;
+ }
+ } while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
+
+int
+iolooper_is_read( IoLooper* iol, int fd )
+{
+ return FD_ISSET(fd, iol->reads_result);
+}
+
+int
+iolooper_is_write( IoLooper* iol, int fd )
+{
+ return FD_ISSET(fd, iol->writes_result);
+}
+
+int
+iolooper_has_operations( IoLooper* iol )
+{
+ return iolooper_fd_count(iol) > 0;
+}
+
+int64_t
+iolooper_now(void)
+{
+#ifdef _WIN32
+ FILETIME now;
+ int64_t now_100ns;
+
+ GetSystemTimeAsFileTime(&now);
+
+ /* Get the time as hundreds of nanosecond intervals since
+ 12:00 AM January 1t 1601 UTC. We don't really need
+ to compute the value relative to the Posix epoch */
+ now_100ns = ((int64_t)now.dwHighDateTime << 32) | now.dwLowDateTime;
+
+ /* 100 ns == 0.1 us == 0.0001 ms */
+ return now_100ns / 10000LL;
+
+#else /* !_WIN32 */
+ struct timeval time_now;
+ return gettimeofday(&time_now, NULL) ? -1 : (int64_t)time_now.tv_sec * 1000LL +
+ time_now.tv_usec / 1000;
+#endif /* !_WIN32 */
+}
+
+int
+iolooper_wait_absolute(IoLooper* iol, int64_t deadline)
+{
+ int64_t timeout = deadline - iolooper_now();
+
+ /* If the deadline has passed, set the timeout to 0, this allows us
+ * to poll the file descriptor nonetheless */
+ if (timeout < 0)
+ timeout = 0;
+
+ return iolooper_wait(iol, timeout);
+}
diff --git a/tools/emulator/opengl/tests/event_injector/iolooper.h b/tools/emulator/opengl/tests/event_injector/iolooper.h
new file mode 100644
index 0000000..4aa3db7
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/iolooper.h
@@ -0,0 +1,91 @@
+/*
+* 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.
+*/
+#ifndef IOLOOPER_H
+#define IOLOOPER_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* An IOLooper is an abstraction for select() */
+
+typedef struct IoLooper IoLooper;
+
+IoLooper* iolooper_new(void);
+void iolooper_free( IoLooper* iol );
+void iolooper_reset( IoLooper* iol );
+
+void iolooper_add_read( IoLooper* iol, int fd );
+void iolooper_add_write( IoLooper* iol, int fd );
+void iolooper_del_read( IoLooper* iol, int fd );
+void iolooper_del_write( IoLooper* iol, int fd );
+
+enum {
+ IOLOOPER_READ = (1<<0),
+ IOLOOPER_WRITE = (1<<1),
+};
+void iolooper_modify( IoLooper* iol, int fd, int oldflags, int newflags);
+
+int iolooper_poll( IoLooper* iol );
+/* Wrapper around select()
+ * Return:
+ * > 0 in case an I/O has occurred, or < 0 on error, or 0 on timeout with
+ * errno set to ETIMEDOUT.
+ */
+int iolooper_wait( IoLooper* iol, int64_t duration );
+
+int iolooper_is_read( IoLooper* iol, int fd );
+int iolooper_is_write( IoLooper* iol, int fd );
+/* Returns 1 if this IoLooper has one or more file descriptor to interact with */
+int iolooper_has_operations( IoLooper* iol );
+/* Gets current time in milliseconds.
+ * Return:
+ * Number of milliseconds corresponded to the current time on success, or -1
+ * on failure.
+ */
+int64_t iolooper_now(void);
+/* Waits for an I/O to occur before specific absolute time.
+ * This routine should be used (instead of iolooper_wait) in cases when multiple
+ * sequential I/O should be completed within given time interval. For instance,
+ * consider the scenario, when "server" does two sequential writes, and "client"
+ * now has to read data transferred with these two distinct writes. It might be
+ * wasteful to do two reads, each with the same (large) timeout. Instead, it
+ * would be better to assign a deadline for both reads before the first read,
+ * and call iolooper_wait_absoulte with the same deadline value:
+ * int64_t deadline = iolooper_now() + TIMEOUT;
+ * if (iolooper_wait_absoulte(iol, deadline)) {
+ * // Process first buffer.
+ * (iolooper_wait_absoulte(iol, deadline)) {
+ * // Process second read
+ * }
+ * }
+ * Param:
+ * iol IoLooper instance for an I/O.
+ * deadline Deadline (absoulte time in milliseconds) before which an I/O should
+ * occur.
+ * Return:
+ * Number of I/O descriptors set in iol, if an I/O has occurred, 0 if no I/O
+ * occurred before the deadline, or -1 on error.
+ */
+int iolooper_wait_absolute(IoLooper* iol, int64_t deadline);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* IOLOOPER_H */
diff --git a/tools/emulator/opengl/tests/event_injector/sockets.c b/tools/emulator/opengl/tests/event_injector/sockets.c
new file mode 100644
index 0000000..a2cc334
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/sockets.c
@@ -0,0 +1,1554 @@
+/*
+* 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.
+*/
+#ifdef __linux__ /* Recent versions of glibc only define EAI_NODATA, which is an
+ extension to the POSIX standard, if _GNU_SOURCE is defined. */
+# define _GNU_SOURCE 1
+#endif
+
+#include "sockets.h"
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+//#include "android/utils/path.h"
+//#include "android/utils/debug.h"
+//#include "android/utils/misc.h"
+//#include "android/utils/system.h"
+
+#define D(...) ((void)0)
+
+#ifdef _WIN32
+# define xxWIN32_LEAN_AND_MEAN
+# define _WIN32_WINNT 0x501
+# include <windows.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#else /* !_WIN32 */
+# include <sys/ioctl.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <netinet/tcp.h>
+# include <netdb.h>
+# if HAVE_UNIX_SOCKETS
+# include <sys/un.h>
+# ifndef UNIX_PATH_MAX
+# define UNIX_PATH_MAX (sizeof(((struct sockaddr_un*)0)->sun_path)-1)
+# endif
+# endif
+#endif /* !_WIN32 */
+
+#define MIN(x,y) ({ typeof(x) _x = (x); typeof(y) _y = (y); _x <= _y ? _x : _y; })
+#define AFREE(p) free(p)
+#define AARRAY_NEW(p,count) (p) = malloc(sizeof(*(p))*(count))
+#define AARRAY_NEW0(p,count) (p) = calloc(sizeof(*(p)),(count))
+
+/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
+ * easily in QEMU since we use SIGALRM to implement periodic timers
+ */
+#ifdef _WIN32
+# define QSOCKET_CALL(_ret,_cmd) \
+ do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
+#else
+# define QSOCKET_CALL(_ret,_cmd) \
+ do { \
+ errno = 0; \
+ do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
+ } while (0);
+#endif
+
+#ifdef _WIN32
+
+#include <errno.h>
+
+static int winsock_error;
+
+#define WINSOCK_ERRORS_LIST \
+ EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
+ EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
+ EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
+ EE(WSAEINTR,EINTR,"interrupted function call") \
+ EE(WSAEALREADY,EALREADY,"operation already in progress") \
+ EE(WSAEBADF,EBADF,"bad file descriptor") \
+ EE(WSAEACCES,EACCES,"permission denied") \
+ EE(WSAEFAULT,EFAULT,"bad address") \
+ EE(WSAEINVAL,EINVAL,"invalid argument") \
+ EE(WSAEMFILE,EMFILE,"too many opened files") \
+ EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
+ EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
+ EE(WSAEALREADY,EAGAIN,"operation already in progress") \
+ EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
+ EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
+ EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
+ EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
+ EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
+ EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
+ EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
+ EE(WSAENETDOWN,ENETDOWN,"network is down") \
+ EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
+ EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
+ EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
+ EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
+ EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
+ EE(WSAEISCONN,EISCONN,"socket is already connected") \
+ EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
+ EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
+ EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
+ EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
+ EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
+ EE(WSAELOOP,ELOOP,"cannot translate name") \
+ EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
+ EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
+ EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
+
+typedef struct {
+ int winsock;
+ int unix;
+ const char* string;
+} WinsockError;
+
+static const WinsockError _winsock_errors[] = {
+#define EE(w,u,s) { w, u, s },
+ WINSOCK_ERRORS_LIST
+#undef EE
+ { -1, -1, NULL }
+};
+
+/* this function reads the latest winsock error code and updates
+ * errno to a matching value. It also returns the new value of
+ * errno.
+ */
+static int
+_fix_errno( void )
+{
+ const WinsockError* werr = _winsock_errors;
+ int unix = EINVAL; /* generic error code */
+
+ winsock_error = WSAGetLastError();
+
+ for ( ; werr->string != NULL; werr++ ) {
+ if (werr->winsock == winsock_error) {
+ unix = werr->unix;
+ break;
+ }
+ }
+ errno = unix;
+ return -1;
+}
+
+static int
+_set_errno( int code )
+{
+ winsock_error = -1;
+ errno = code;
+ return -1;
+}
+
+/* this function returns a string describing the latest Winsock error */
+const char*
+_errno_str(void)
+{
+ const WinsockError* werr = _winsock_errors;
+ const char* result = NULL;
+
+ for ( ; werr->string; werr++ ) {
+ if (werr->winsock == winsock_error) {
+ result = werr->string;
+ break;
+ }
+ }
+
+ if (result == NULL) {
+ result = "Unknown socket error";
+ }
+ return result;
+}
+#else
+static int
+_fix_errno( void )
+{
+ return -1;
+}
+
+static int
+_set_errno( int code )
+{
+ errno = code;
+ return -1;
+}
+#endif
+
+/* socket types */
+
+static int
+socket_family_to_bsd( SocketFamily family )
+{
+ switch (family) {
+ case SOCKET_INET: return AF_INET;
+ case SOCKET_IN6: return AF_INET6;
+#if HAVE_UNIX_SOCKETS
+ case SOCKET_UNIX: return AF_LOCAL;
+#endif
+ default: return -1;
+ }
+}
+
+static int
+socket_type_to_bsd( SocketType type )
+{
+ switch (type) {
+ case SOCKET_DGRAM: return SOCK_DGRAM;
+ case SOCKET_STREAM: return SOCK_STREAM;
+ default: return 0;
+ }
+}
+
+static SocketType
+socket_type_from_bsd( int type )
+{
+ switch (type) {
+ case SOCK_DGRAM: return SOCKET_DGRAM;
+ case SOCK_STREAM: return SOCKET_STREAM;
+ default: return (SocketType) SOCKET_UNSPEC;
+ }
+}
+
+#if 0
+static int
+socket_type_check( SocketType type )
+{
+ return (type == SOCKET_DGRAM || type == SOCKET_STREAM);
+}
+#endif
+
+typedef union {
+ struct sockaddr sa[1];
+ struct sockaddr_in in[1];
+#if HAVE_IN6_SOCKETS
+ struct sockaddr_in6 in6[1];
+#endif
+#if HAVE_UNIX_SOCKETS
+ struct sockaddr_un un[1];
+#endif
+} sockaddr_storage;
+
+/* socket addresses */
+
+void
+sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port )
+{
+ a->family = SOCKET_INET;
+ a->u.inet.port = port;
+ a->u.inet.address = ip;
+}
+
+void
+sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port )
+{
+ a->family = SOCKET_IN6;
+ a->u.in6.port = port;
+ memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) );
+}
+
+void
+sock_address_init_unix( SockAddress* a, const char* path )
+{
+ a->family = SOCKET_UNIX;
+ a->u._unix.path = strdup(path ? path : "");
+ a->u._unix.owner = 1;
+}
+
+void sock_address_done( SockAddress* a )
+{
+ if (a->family == SOCKET_UNIX && a->u._unix.owner) {
+ a->u._unix.owner = 0;
+ free((char*)a->u._unix.path);
+ }
+}
+
+static char*
+format_char( char* buf, char* end, int c )
+{
+ if (buf < end) {
+ if (buf+1 == end) {
+ *buf++ = 0;
+ } else {
+ *buf++ = (char) c;
+ *buf = 0;
+ }
+ }
+ return buf;
+}
+
+static char*
+format_str( char* buf, char* end, const char* str )
+{
+ int len = strlen(str);
+ int avail = end - buf;
+
+ if (len > avail)
+ len = avail;
+
+ memcpy( buf, str, len );
+ buf += len;
+
+ if (buf == end)
+ buf[-1] = 0;
+ else
+ buf[0] = 0;
+
+ return buf;
+}
+
+static char*
+format_unsigned( char* buf, char* end, unsigned val )
+{
+ char temp[16];
+ int nn;
+
+ for ( nn = 0; val != 0; nn++ ) {
+ int rem = val % 10;
+ temp[nn] = '0'+rem;
+ val /= 10;
+ }
+
+ if (nn == 0)
+ temp[nn++] = '0';
+
+ while (nn > 0)
+ buf = format_char(buf, end, temp[--nn]);
+
+ return buf;
+}
+
+static char*
+format_hex( char* buf, char* end, unsigned val, int ndigits )
+{
+ int shift = 4*ndigits;
+ static const char hex[16] = "0123456789abcdef";
+
+ while (shift >= 0) {
+ buf = format_char(buf, end, hex[(val >> shift) & 15]);
+ shift -= 4;
+ }
+ return buf;
+}
+
+static char*
+format_ip4( char* buf, char* end, uint32_t ip )
+{
+ buf = format_unsigned( buf, end, (unsigned)(ip >> 24) );
+ buf = format_char( buf, end, '.');
+ buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255));
+ buf = format_char( buf, end, '.');
+ buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255));
+ buf = format_char( buf, end, '.');
+ buf = format_unsigned( buf, end, (unsigned)(ip & 255));
+ return buf;
+}
+
+static char*
+format_ip6( char* buf, char* end, const uint8_t* ip6 )
+{
+ int nn;
+ for (nn = 0; nn < 8; nn++) {
+ int val = (ip6[0] << 16) | ip6[1];
+ ip6 += 2;
+ if (nn > 0)
+ buf = format_char(buf, end, ':');
+ if (val == 0)
+ continue;
+ buf = format_hex(buf, end, val, 4);
+ }
+ return buf;
+}
+
+const char*
+sock_address_to_string( const SockAddress* a )
+{
+ static char buf0[PATH_MAX];
+ char *buf = buf0, *end = buf + sizeof(buf0);
+
+ switch (a->family) {
+ case SOCKET_INET:
+ buf = format_ip4( buf, end, a->u.inet.address );
+ buf = format_char( buf, end, ':' );
+ buf = format_unsigned( buf, end, (unsigned) a->u.inet.port );
+ break;
+
+ case SOCKET_IN6:
+ buf = format_ip6( buf, end, a->u.in6.address );
+ buf = format_char( buf, end, ':' );
+ buf = format_unsigned( buf, end, (unsigned) a->u.in6.port );
+ break;
+
+ case SOCKET_UNIX:
+ buf = format_str( buf, end, a->u._unix.path );
+ break;
+
+ default:
+ return NULL;
+ }
+
+ return buf0;
+}
+
+int
+sock_address_equal( const SockAddress* a, const SockAddress* b )
+{
+ if (a->family != b->family)
+ return 0;
+
+ switch (a->family) {
+ case SOCKET_INET:
+ return (a->u.inet.address == b->u.inet.address &&
+ a->u.inet.port == b->u.inet.port);
+
+ case SOCKET_IN6:
+ return (!memcmp(a->u.in6.address, b->u.in6.address, 16) &&
+ a->u.in6.port == b->u.in6.port);
+
+ case SOCKET_UNIX:
+ return (!strcmp(a->u._unix.path, b->u._unix.path));
+
+ default:
+ return 0;
+ }
+}
+
+int
+sock_address_get_port( const SockAddress* a )
+{
+ switch (a->family) {
+ case SOCKET_INET:
+ return a->u.inet.port;
+ case SOCKET_IN6:
+ return a->u.in6.port;
+ default:
+ return -1;
+ }
+}
+
+void
+sock_address_set_port( SockAddress* a, uint16_t port )
+{
+ switch (a->family) {
+ case SOCKET_INET:
+ a->u.inet.port = port;
+ break;
+ case SOCKET_IN6:
+ a->u.in6.port = port;
+ break;
+ default:
+ ;
+ }
+}
+
+const char*
+sock_address_get_path( const SockAddress* a )
+{
+ if (a->family == SOCKET_UNIX)
+ return a->u._unix.path;
+ else
+ return NULL;
+}
+
+int
+sock_address_get_ip( const SockAddress* a )
+{
+ if (a->family == SOCKET_INET)
+ return a->u.inet.address;
+
+ return -1;
+}
+
+#if 0
+char*
+bufprint_sock_address( char* p, char* end, const SockAddress* a )
+{
+ switch (a->family) {
+ case SOCKET_INET:
+ {
+ uint32_t ip = a->u.inet.address;
+
+ return bufprint( p, end, "%d.%d.%d.%d:%d",
+ (ip >> 24) & 255, (ip >> 16) & 255,
+ (ip >> 8) & 255, ip & 255,
+ a->u.inet.port );
+ }
+ case SOCKET_IN6:
+ {
+ int nn = 0;
+ const char* column = "";
+ const uint8_t* tab = a->u.in6.address;
+ for (nn = 0; nn < 16; nn += 2) {
+ p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]);
+ column = ":";
+ }
+ return bufprint(p, end, ":%d", a->u.in6.port);
+ }
+ case SOCKET_UNIX:
+ {
+ return bufprint(p, end, "%s", a->u._unix.path);
+ }
+ default:
+ return p;
+ }
+}
+#endif
+
+static int
+sock_address_to_bsd( const SockAddress* a, sockaddr_storage* paddress, socklen_t *psize )
+{
+ switch (a->family) {
+ case SOCKET_INET:
+ {
+ struct sockaddr_in* dst = paddress->in;
+
+ *psize = sizeof(*dst);
+
+ memset( paddress, 0, *psize );
+
+ dst->sin_family = AF_INET;
+ dst->sin_port = htons(a->u.inet.port);
+ dst->sin_addr.s_addr = htonl(a->u.inet.address);
+ }
+ break;
+
+#if HAVE_IN6_SOCKETS
+ case SOCKET_IN6:
+ {
+ struct sockaddr_in6* dst = paddress->in6;
+
+ *psize = sizeof(*dst);
+
+ memset( paddress, 0, *psize );
+
+ dst->sin6_family = AF_INET6;
+ dst->sin6_port = htons(a->u.in6.port);
+ memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 );
+ }
+ break;
+#endif /* HAVE_IN6_SOCKETS */
+
+#if HAVE_UNIX_SOCKETS
+ case SOCKET_UNIX:
+ {
+ int slen = strlen(a->u._unix.path);
+ struct sockaddr_un* dst = paddress->un;
+
+ if (slen >= (int)UNIX_PATH_MAX)
+ return -1;
+
+ memset( dst, 0, sizeof(*dst) );
+
+ dst->sun_family = AF_LOCAL;
+ memcpy( dst->sun_path, a->u._unix.path, slen );
+ dst->sun_path[slen] = 0;
+
+ *psize = (char*)&dst->sun_path[slen+1] - (char*)dst;
+ }
+ break;
+#endif /* HAVE_UNIX_SOCKETS */
+
+ default:
+ return _set_errno(EINVAL);
+ }
+
+ return 0;
+}
+
+static int
+sock_address_from_bsd( SockAddress* a, const void* from, size_t fromlen )
+{
+ switch (((struct sockaddr *)from)->sa_family) {
+ case AF_INET:
+ {
+ const struct sockaddr_in* src = from;
+
+ if (fromlen < sizeof(*src))
+ return _set_errno(EINVAL);
+
+ a->family = SOCKET_INET;
+ a->u.inet.port = ntohs(src->sin_port);
+ a->u.inet.address = ntohl(src->sin_addr.s_addr);
+ }
+ break;
+
+#ifdef HAVE_IN6_SOCKETS
+ case AF_INET6:
+ {
+ const struct sockaddr_in6* src = from;
+
+ if (fromlen < sizeof(*src))
+ return _set_errno(EINVAL);
+
+ a->family = SOCKET_IN6;
+ a->u.in6.port = ntohs(src->sin6_port);
+ memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16);
+ }
+ break;
+#endif
+
+#ifdef HAVE_UNIX_SOCKETS
+ case AF_LOCAL:
+ {
+ const struct sockaddr_un* src = from;
+ char* end;
+
+ if (fromlen < sizeof(*src))
+ return _set_errno(EINVAL);
+
+ /* check that the path is zero-terminated */
+ end = memchr(src->sun_path, 0, UNIX_PATH_MAX);
+ if (end == NULL)
+ return _set_errno(EINVAL);
+
+ a->family = SOCKET_UNIX;
+ a->u._unix.owner = 1;
+ a->u._unix.path = strdup(src->sun_path);
+ }
+ break;
+#endif
+
+ default:
+ return _set_errno(EINVAL);
+ }
+ return 0;
+}
+
+
+int
+sock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t port, int preferIn6 )
+{
+ struct addrinfo hints[1];
+ struct addrinfo* res;
+ int ret;
+
+ memset(hints, 0, sizeof(hints));
+ hints->ai_family = preferIn6 ? AF_INET6 : AF_UNSPEC;
+
+ ret = getaddrinfo(hostname, NULL, hints, &res);
+ if (ret != 0) {
+ int err;
+
+ switch (ret) {
+ case EAI_AGAIN: /* server is down */
+ case EAI_FAIL: /* server is sick */
+ err = EHOSTDOWN;
+ break;
+
+#ifdef EAI_NODATA
+ case EAI_NODATA:
+#endif
+ case EAI_NONAME:
+ err = ENOENT;
+ break;
+
+ case EAI_MEMORY:
+ err = ENOMEM;
+ break;
+
+ default:
+ err = EINVAL;
+ }
+ return _set_errno(err);
+ }
+
+ /* Parse the returned list of addresses. */
+ {
+ struct addrinfo* res_ipv4 = NULL;
+ struct addrinfo* res_ipv6 = NULL;
+ struct addrinfo* r;
+
+ /* If preferIn6 is false, we stop on the first IPv4 address,
+ * otherwise, we stop on the first IPv6 one
+ */
+ for (r = res; r != NULL; r = r->ai_next) {
+ if (r->ai_family == AF_INET && res_ipv4 == NULL) {
+ res_ipv4 = r;
+ if (!preferIn6)
+ break;
+ }
+ else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) {
+ res_ipv6 = r;
+ if (preferIn6)
+ break;
+ }
+ }
+
+ /* Select the best address in 'r', which will be NULL
+ * if there is no corresponding address.
+ */
+ if (preferIn6) {
+ r = res_ipv6;
+ if (r == NULL)
+ r = res_ipv4;
+ } else {
+ r = res_ipv4;
+ if (r == NULL)
+ r = res_ipv6;
+ }
+
+ if (r == NULL) {
+ ret = _set_errno(ENOENT);
+ goto Exit;
+ }
+
+ /* Convert to a SockAddress */
+ ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen );
+ if (ret < 0)
+ goto Exit;
+ }
+
+ /* need to set the port */
+ switch (a->family) {
+ case SOCKET_INET: a->u.inet.port = port; break;
+ case SOCKET_IN6: a->u.in6.port = port; break;
+ default: ;
+ }
+
+Exit:
+ freeaddrinfo(res);
+ return ret;
+}
+
+/* The Winsock headers for mingw lack some definitions */
+#ifndef AI_ADDRCONFIG
+# define AI_ADDRCONFIG 0
+#endif
+
+SockAddress**
+sock_address_list_create( const char* hostname,
+ const char* port,
+ unsigned flags )
+{
+ SockAddress** list = NULL;
+ SockAddress* addr;
+ int nn, count, ret;
+ struct addrinfo ai, *res, *e;
+
+ memset(&ai, 0, sizeof(ai));
+ ai.ai_flags |= AI_ADDRCONFIG;
+ ai.ai_family = PF_UNSPEC;
+
+ if (flags & SOCKET_LIST_FORCE_INET)
+ ai.ai_family = PF_INET;
+ else if (flags & SOCKET_LIST_FORCE_IN6)
+ ai.ai_family = PF_INET6;
+
+ if (flags & SOCKET_LIST_PASSIVE)
+ ai.ai_flags |= AI_PASSIVE;
+ else
+ ai.ai_flags |= AI_CANONNAME;
+
+ if (flags & SOCKET_LIST_DGRAM)
+ ai.ai_socktype = SOCK_DGRAM;
+
+ while (1) {
+ struct addrinfo hints = ai;
+
+ ret = getaddrinfo(hostname, port, &hints, &res);
+ if (ret == 0)
+ break;
+
+ switch (ret) {
+#ifdef EAI_ADDRFAMILY
+ case EAI_ADDRFAMILY:
+#endif
+ case EAI_NODATA:
+ _set_errno(ENOENT);
+ break;
+ case EAI_FAMILY:
+ _set_errno(EAFNOSUPPORT);
+ break;
+ case EAI_AGAIN:
+ _set_errno(EAGAIN);
+ break;
+#ifdef EAI_SYSTEM
+ case EAI_SYSTEM:
+ if (errno == EINTR)
+ continue;
+ break;
+#endif
+ default:
+ _set_errno(EINVAL);
+ }
+ return NULL;
+ }
+
+ /* allocate result list */
+ for (count = 0, e = res; e != NULL; e = e->ai_next)
+ count += 1;
+
+ AARRAY_NEW(list, count+1);
+ AARRAY_NEW(addr, count);
+
+ for (nn = 0, e = res; e != NULL; e = e->ai_next) {
+
+ ret = sock_address_from_bsd(addr, e->ai_addr, e->ai_addrlen);
+ if (ret < 0)
+ continue;
+
+ list[nn++] = addr++;
+ }
+ list[nn] = NULL;
+ freeaddrinfo(res);
+ return list;
+}
+
+SockAddress**
+sock_address_list_create2(const char* host_and_port, unsigned flags )
+{
+ char host_name[512];
+ const char* actual_host_name = "localhost";
+ // Parse host and port name.
+ const char* port_name = strchr(host_and_port, ':');
+ if (port_name != NULL) {
+ int to_copy = MIN((int)sizeof(host_name)-1, port_name - host_and_port);
+ if (to_copy != 0) {
+ memcpy(host_name, host_and_port, to_copy);
+ host_name[to_copy] = '\0';
+ actual_host_name = host_name;
+ port_name++;
+ } else {
+ return NULL;
+ }
+ } else {
+ port_name = host_and_port;
+ }
+ // Make sure that port_name is not empty.
+ if (port_name[0] == '\0') {
+ return NULL;
+ }
+ return sock_address_list_create(actual_host_name, port_name, flags);
+}
+
+void
+sock_address_list_free( SockAddress** list )
+{
+ int nn;
+ SockAddress* addr;
+
+ if (list == NULL)
+ return;
+
+ addr = list[0];
+ for (nn = 0; list[nn] != NULL; nn++) {
+ sock_address_done(list[nn]);
+ list[nn] = NULL;
+ }
+ AFREE(addr);
+ AFREE(list);
+}
+
+int
+sock_address_get_numeric_info( SockAddress* a,
+ char* host,
+ size_t hostlen,
+ char* serv,
+ size_t servlen )
+{
+ struct sockaddr* saddr;
+ socklen_t slen;
+ int ret;
+
+ switch (a->family) {
+ case SOCKET_INET:
+ saddr = (struct sockaddr*) &a->u.inet.address;
+ slen = sizeof(a->u.inet.address);
+ break;
+
+#if HAVE_IN6_SOCKET
+ case SOCKET_IN6:
+ saddr = (struct sockaddr*) &a->u.in6.address;
+ slen = sizeof(a->u.in6.address);
+ break;
+#endif
+ default:
+ return _set_errno(EINVAL);
+ }
+
+ ret = getnameinfo( saddr, slen, host, hostlen, serv, servlen,
+ NI_NUMERICHOST | NI_NUMERICSERV );
+
+ switch (ret) {
+ case 0:
+ break;
+ case EAI_AGAIN:
+ ret = EAGAIN;
+ break;
+ default:
+ ret = EINVAL;
+ }
+ return ret;
+}
+
+int
+socket_create( SocketFamily family, SocketType type )
+{
+ int ret;
+ int sfamily = socket_family_to_bsd(family);
+ int stype = socket_type_to_bsd(type);
+
+ if (sfamily < 0 || stype < 0) {
+ return _set_errno(EINVAL);
+ }
+
+ QSOCKET_CALL(ret, socket(sfamily, stype, 0));
+ if (ret < 0)
+ return _fix_errno();
+
+ return ret;
+}
+
+
+int
+socket_create_inet( SocketType type )
+{
+ return socket_create( SOCKET_INET, type );
+}
+
+#if HAVE_IN6_SOCKETS
+int
+socket_create_in6 ( SocketType type )
+{
+ return socket_create( SOCKET_IN6, type );
+}
+#endif
+
+#if HAVE_UNIX_SOCKETS
+int
+socket_create_unix( SocketType type )
+{
+ return socket_create( SOCKET_UNIX, type );
+}
+#endif
+
+int socket_can_read(int fd)
+{
+#ifdef _WIN32
+ unsigned long opt;
+
+ if (ioctlsocket(fd, FIONREAD, &opt) < 0)
+ return 0;
+
+ return opt;
+#else
+ int opt;
+
+ if (ioctl(fd, FIONREAD, &opt) < 0)
+ return 0;
+
+ return opt;
+#endif
+}
+
+#define SOCKET_CALL(cmd) \
+ int ret; \
+ QSOCKET_CALL(ret, (cmd)); \
+ if (ret < 0) \
+ return _fix_errno(); \
+ return ret; \
+
+int
+socket_send(int fd, const void* buf, int buflen)
+{
+ SOCKET_CALL(send(fd, buf, buflen, 0))
+}
+
+int
+socket_send_oob( int fd, const void* buf, int buflen )
+{
+ SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
+}
+
+int
+socket_sendto(int fd, const void* buf, int buflen, const SockAddress* to)
+{
+ sockaddr_storage sa;
+ socklen_t salen;
+
+ if (sock_address_to_bsd(to, &sa, &salen) < 0)
+ return -1;
+
+ SOCKET_CALL(sendto(fd, buf, buflen, 0, sa.sa, salen));
+}
+
+int
+socket_recv(int fd, void* buf, int len)
+{
+ SOCKET_CALL(recv(fd, buf, len, 0));
+}
+
+int
+socket_recvfrom(int fd, void* buf, int len, SockAddress* from)
+{
+ sockaddr_storage sa;
+ socklen_t salen = sizeof(sa);
+ int ret;
+
+ QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,sa.sa,&salen));
+ if (ret < 0)
+ return _fix_errno();
+
+ if (sock_address_from_bsd(from, &sa, salen) < 0)
+ return -1;
+
+ return ret;
+}
+
+int
+socket_connect( int fd, const SockAddress* address )
+{
+ sockaddr_storage addr;
+ socklen_t addrlen;
+
+ if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
+ return -1;
+
+ SOCKET_CALL(connect(fd,addr.sa,addrlen));
+}
+
+int
+socket_bind( int fd, const SockAddress* address )
+{
+ sockaddr_storage addr;
+ socklen_t addrlen;
+
+ if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
+ return -1;
+
+ SOCKET_CALL(bind(fd, addr.sa, addrlen));
+}
+
+int
+socket_get_address( int fd, SockAddress* address )
+{
+ sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ int ret;
+
+ QSOCKET_CALL(ret, getsockname(fd, addr.sa, &addrlen));
+ if (ret < 0)
+ return _fix_errno();
+
+ return sock_address_from_bsd(address, &addr, addrlen);
+}
+
+int
+socket_get_peer_address( int fd, SockAddress* address )
+{
+ sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ int ret;
+
+ QSOCKET_CALL(ret, getpeername(fd, addr.sa, &addrlen));
+ if (ret < 0)
+ return _fix_errno();
+
+ return sock_address_from_bsd(address, &addr, addrlen);
+}
+
+int
+socket_listen( int fd, int backlog )
+{
+ SOCKET_CALL(listen(fd, backlog));
+}
+
+int
+socket_accept( int fd, SockAddress* address )
+{
+ sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ int ret;
+
+ QSOCKET_CALL(ret, accept(fd, addr.sa, &addrlen));
+ if (ret < 0)
+ return _fix_errno();
+
+ if (address) {
+ if (sock_address_from_bsd(address, &addr, addrlen) < 0) {
+ socket_close(ret);
+ return -1;
+ }
+ }
+ return ret;
+}
+
+static int
+socket_getoption(int fd, int domain, int option, int defaut)
+{
+ int ret;
+ while (1) {
+#ifdef _WIN32
+ DWORD opt = (DWORD)-1;
+#else
+ int opt = -1;
+#endif
+ socklen_t optlen = sizeof(opt);
+ ret = getsockopt(fd, domain, option, (char*)&opt, &optlen);
+ if (ret == 0)
+ return (int)opt;
+ if (errno != EINTR)
+ return defaut;
+ }
+#undef OPT_CAST
+}
+
+
+SocketType socket_get_type(int fd)
+{
+ int so_type = socket_getoption(fd, SOL_SOCKET, SO_TYPE, -1);
+ return socket_type_from_bsd(so_type);
+}
+
+int socket_set_nonblock(int fd)
+{
+#ifdef _WIN32
+ unsigned long opt = 1;
+ return ioctlsocket(fd, FIONBIO, &opt);
+#else
+ int flags = fcntl(fd, F_GETFL);
+ return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+#endif
+}
+
+int socket_set_blocking(int fd)
+{
+#ifdef _WIN32
+ unsigned long opt = 0;
+ return ioctlsocket(fd, FIONBIO, &opt);
+#else
+ int flags = fcntl(fd, F_GETFL);
+ return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+#endif
+}
+
+static int
+socket_setoption(int fd, int domain, int option, int _flag)
+{
+#ifdef _WIN32
+ DWORD flag = (DWORD) _flag;
+#else
+ int flag = _flag;
+#endif
+ return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) );
+}
+
+int socket_set_xreuseaddr(int fd)
+{
+#ifdef _WIN32
+ /* on Windows, SO_REUSEADDR is used to indicate that several programs can
+ * bind to the same port. this is completely different from the Unix
+ * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent
+ * this.
+ */
+ return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
+#else
+ return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1);
+#endif
+}
+
+
+int socket_set_oobinline(int fd)
+{
+ return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
+}
+
+
+int socket_set_nodelay(int fd)
+{
+ return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
+}
+
+int socket_set_ipv6only(int fd)
+{
+/* IPV6_ONLY is only supported since Vista on Windows,
+ * and the Mingw headers lack its definition anyway.
+ */
+#if defined(_WIN32) && !defined(IPV6_V6ONLY)
+ return 0;
+#else
+ return socket_setoption(fd, IPPROTO_IPV6, IPV6_V6ONLY, 1);
+#endif
+}
+
+
+int socket_get_error(int fd)
+{
+ return socket_getoption(fd, SOL_SOCKET, SO_ERROR, -1);
+}
+
+#ifdef _WIN32
+#include <stdlib.h>
+
+static void socket_cleanup(void)
+{
+ WSACleanup();
+}
+
+int socket_init(void)
+{
+ WSADATA Data;
+ int ret, err;
+
+ ret = WSAStartup(MAKEWORD(2,2), &Data);
+ if (ret != 0) {
+ err = WSAGetLastError();
+ return -1;
+ }
+ atexit(socket_cleanup);
+ return 0;
+}
+
+#else /* !_WIN32 */
+
+int socket_init(void)
+{
+ return 0; /* nothing to do on Unix */
+}
+
+#endif /* !_WIN32 */
+
+#ifdef _WIN32
+
+void
+socket_close( int fd )
+{
+ int old_errno = errno;
+
+ shutdown( fd, SD_BOTH );
+ /* we want to drain the socket before closing it */
+ //qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
+ closesocket(fd);
+
+ errno = old_errno;
+}
+
+#else /* !_WIN32 */
+
+#include <unistd.h>
+
+void
+socket_close( int fd )
+{
+ int old_errno = errno;
+
+ shutdown( fd, SHUT_RDWR );
+ close( fd );
+
+ errno = old_errno;
+}
+
+#endif /* !_WIN32 */
+
+
+static int
+socket_bind_server( int s, const SockAddress* to, SocketType type )
+{
+ socket_set_xreuseaddr(s);
+
+ if (socket_bind(s, to) < 0) {
+ D("could not bind server socket address %s: %s",
+ sock_address_to_string(to), errno_str);
+ goto FAIL;
+ }
+
+ if (type == SOCKET_STREAM) {
+ if (socket_listen(s, 4) < 0) {
+ D("could not listen server socket %s: %s",
+ sock_address_to_string(to), errno_str);
+ goto FAIL;
+ }
+ }
+ return s;
+
+FAIL:
+ socket_close(s);
+ return -1;
+}
+
+
+static int
+socket_connect_client( int s, const SockAddress* to )
+{
+ if (socket_connect(s, to) < 0) {
+ D( "could not connect client socket to %s: %s\n",
+ sock_address_to_string(to), errno_str );
+ socket_close(s);
+ return -1;
+ }
+
+ socket_set_nonblock( s );
+ return s;
+}
+
+
+static int
+socket_in_server( int address, int port, SocketType type )
+{
+ SockAddress addr;
+ int s;
+
+ sock_address_init_inet( &addr, address, port );
+ s = socket_create_inet( type );
+ if (s < 0)
+ return -1;
+
+ return socket_bind_server( s, &addr, type );
+}
+
+
+static int
+socket_in_client( SockAddress* to, SocketType type )
+{
+ int s;
+
+ s = socket_create_inet( type );
+ if (s < 0) return -1;
+
+ return socket_connect_client( s, to );
+}
+
+
+int
+socket_loopback_server( int port, SocketType type )
+{
+ return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
+}
+
+int
+socket_loopback_client( int port, SocketType type )
+{
+ SockAddress addr;
+
+ sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
+ return socket_in_client( &addr, type );
+}
+
+
+int
+socket_network_client( const char* host, int port, SocketType type )
+{
+ SockAddress addr;
+
+ if (sock_address_init_resolve( &addr, host, port, 0) < 0)
+ return -1;
+
+ return socket_in_client( &addr, type );
+}
+
+
+int
+socket_anyaddr_server( int port, SocketType type )
+{
+ return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
+}
+
+int
+socket_accept_any( int server_fd )
+{
+ int fd;
+
+ QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
+ if (fd < 0) {
+ D( "could not accept client connection from fd %d: %s",
+ server_fd, errno_str );
+ return -1;
+ }
+
+ /* set to non-blocking */
+ socket_set_nonblock( fd );
+ return fd;
+}
+
+
+#if HAVE_UNIX_SOCKETS
+
+int
+socket_unix_server( const char* name, SocketType type )
+{
+ SockAddress addr;
+ int s, ret;
+
+ s = socket_create_unix( type );
+ if (s < 0)
+ return -1;
+
+ sock_address_init_unix( &addr, name );
+
+ do {
+ ret = unlink( name );
+ } while (ret < 0 && errno == EINTR);
+
+ ret = socket_bind_server( s, &addr, type );
+
+ sock_address_done( &addr );
+ return ret;
+}
+
+int
+socket_unix_client( const char* name, SocketType type )
+{
+ SockAddress addr;
+ int s, ret;
+
+ s = socket_create_unix(type);
+ if (s < 0)
+ return -1;
+
+ sock_address_init_unix( &addr, name );
+
+ ret = socket_connect_client( s, &addr );
+
+ sock_address_done( &addr );
+ return ret;
+}
+
+#endif /* HAVE_UNIX_SOCKETS */
+
+
+
+int
+socket_pair(int *fd1, int *fd2)
+{
+#ifndef _WIN32
+ int fds[2];
+ int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
+
+ if (!ret) {
+ socket_set_nonblock(fds[0]);
+ socket_set_nonblock(fds[1]);
+ *fd1 = fds[0];
+ *fd2 = fds[1];
+ }
+ return ret;
+#else /* _WIN32 */
+ /* on Windows, select() only works with network sockets, which
+ * means we absolutely cannot use Win32 PIPEs to implement
+ * socket pairs with the current event loop implementation.
+ * We're going to do like Cygwin: create a random pair
+ * of localhost TCP sockets and connect them together
+ */
+ int s0, s1, s2, port;
+ struct sockaddr_in sockin;
+ socklen_t len;
+
+ /* first, create the 'server' socket.
+ * a port number of 0 means 'any port between 1024 and 5000.
+ * see Winsock bind() documentation for details */
+ s0 = socket_loopback_server( 0, SOCK_STREAM );
+ if (s0 < 0)
+ return -1;
+
+ /* now connect a client socket to it, we first need to
+ * extract the server socket's port number */
+ len = sizeof sockin;
+ if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
+ closesocket (s0);
+ return -1;
+ }
+
+ port = ntohs(sockin.sin_port);
+ s2 = socket_loopback_client( port, SOCK_STREAM );
+ if (s2 < 0) {
+ closesocket(s0);
+ return -1;
+ }
+
+ /* we need to accept the connection on the server socket
+ * this will create the second socket for the pair
+ */
+ len = sizeof sockin;
+ s1 = accept(s0, (struct sockaddr*) &sockin, &len);
+ if (s1 == INVALID_SOCKET) {
+ closesocket (s0);
+ closesocket (s2);
+ return -1;
+ }
+ socket_set_nonblock(s1);
+
+ /* close server socket */
+ closesocket(s0);
+ *fd1 = s1;
+ *fd2 = s2;
+ return 0;
+#endif /* _WIN32 */
+}
+
+
+
+int
+socket_mcast_inet_add_membership( int s, uint32_t ip )
+{
+ struct ip_mreq imr;
+
+ imr.imr_multiaddr.s_addr = htonl(ip);
+ imr.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (const char *)&imr,
+ sizeof(struct ip_mreq)) < 0 )
+ {
+ return _fix_errno();
+ }
+ return 0;
+}
+
+int
+socket_mcast_inet_drop_membership( int s, uint32_t ip )
+{
+ struct ip_mreq imr;
+
+ imr.imr_multiaddr.s_addr = htonl(ip);
+ imr.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (const char *)&imr,
+ sizeof(struct ip_mreq)) < 0 )
+ {
+ return _fix_errno();
+ }
+ return 0;
+}
+
+int
+socket_mcast_inet_set_loop( int s, int enabled )
+{
+ return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
+}
+
+int
+socket_mcast_inet_set_ttl( int s, int ttl )
+{
+ return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
+}
+
+
+char*
+host_name( void )
+{
+ static char buf[256]; /* 255 is the max host name length supported by DNS */
+ int ret;
+
+ QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));
+
+ if (ret < 0)
+ return "localhost";
+ else
+ return buf;
+}
diff --git a/tools/emulator/opengl/tests/event_injector/sockets.h b/tools/emulator/opengl/tests/event_injector/sockets.h
new file mode 100644
index 0000000..ea48c5f
--- /dev/null
+++ b/tools/emulator/opengl/tests/event_injector/sockets.h
@@ -0,0 +1,432 @@
+/*
+* 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.
+*/
+/* headers to use the BSD sockets */
+#ifndef ANDROID_SOCKET_H
+#define ANDROID_SOCKET_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* we're going to hide the implementation details of sockets behind
+ * a simple wrapper interface declared here.
+ *
+ * all socket operations set the global 'errno' variable on error.
+ * this is unlike Winsock which instead modifies another internal
+ * variable accessed through WSAGetLastError() and WSASetLastError()
+ */
+
+/* the wrapper will convert any Winsock error message into an errno
+ * code for you. There are however a few standard Unix error codes
+ * that are not defined by the MS C library headers, so we add them
+ * here. We use the official Winsock error codes, which are documented
+ * even though we don't want to include the Winsock headers
+ */
+#ifdef _WIN32
+# ifndef EINTR
+# define EINTR 10004
+# endif
+# ifndef EAGAIN
+# define EAGAIN 10035
+# endif
+# ifndef EWOULDBLOCK
+# define EWOULDBLOCK EAGAIN
+# endif
+# ifndef EINPROGRESS
+# define EINPROGRESS 10036
+# endif
+# ifndef EALREADY
+# define EALREADY 10037
+# endif
+# ifndef EDESTADDRREQ
+# define EDESTADDRREQ 10039
+# endif
+# ifndef EMSGSIZE
+# define EMSGSIZE 10040
+# endif
+# ifndef EPROTOTYPE
+# define EPROTOTYPE 10041
+# endif
+# ifndef ENOPROTOOPT
+# define ENOPROTOOPT 10042
+# endif
+# ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT 10047
+# endif
+# ifndef EADDRINUSE
+# define EADDRINUSE 10048
+# endif
+# ifndef EADDRNOTAVAIL
+# define EADDRNOTAVAIL 10049
+# endif
+# ifndef ENETDOWN
+# define ENETDOWN 10050
+# endif
+# ifndef ENETUNREACH
+# define ENETUNREACH 10051
+# endif
+# ifndef ENETRESET
+# define ENETRESET 10052
+# endif
+# ifndef ECONNABORTED
+# define ECONNABORTED 10053
+# endif
+# ifndef ECONNRESET
+# define ECONNRESET 10054
+# endif
+# ifndef ENOBUFS
+# define ENOBUFS 10055
+# endif
+# ifndef EISCONN
+# define EISCONN 10056
+# endif
+# ifndef ENOTCONN
+# define ENOTCONN 10057
+# endif
+# ifndef ESHUTDOWN
+# define ESHUTDOWN 10058
+# endif
+# ifndef ETOOMANYREFS
+# define ETOOMANYREFS 10059
+# endif
+# ifndef ETIMEDOUT
+# define ETIMEDOUT 10060
+# endif
+# ifndef ECONNREFUSED
+# define ECONNREFUSED 10061
+# endif
+# ifndef ELOOP
+# define ELOOP 10062
+# endif
+# ifndef EHOSTDOWN
+# define EHOSTDOWN 10064
+# endif
+# ifndef EHOSTUNREACH
+# define EHOSTUNREACH 10065
+# endif
+#endif /* _WIN32 */
+
+/* Define 'errno_str' as a handy macro to return the string
+ * corresponding to a given errno code. On Unix, this is
+ * equivalent to strerror(errno), but on Windows, this will
+ * take care of Winsock-originated errors as well.
+ */
+#ifdef _WIN32
+ extern const char* _errno_str(void);
+# define errno_str _errno_str()
+#else
+# define errno_str strerror(errno)
+#endif
+
+/* always enable IPv6 sockets for now.
+ * the QEMU internal router is not capable of
+ * supporting them, but we plan to replace it
+ * with something better in the future.
+ */
+#define HAVE_IN6_SOCKETS 1
+
+/* Unix sockets are not available on Win32 */
+#ifndef _WIN32
+# define HAVE_UNIX_SOCKETS 1
+#endif
+
+/* initialize the socket sub-system. this must be called before
+ * using any of the declarations below.
+ */
+int socket_init( void );
+
+/* return the name of the current host */
+char* host_name( void );
+
+/* supported socket types */
+typedef enum {
+ SOCKET_DGRAM = 0,
+ SOCKET_STREAM
+} SocketType;
+
+/* supported socket families */
+typedef enum {
+ SOCKET_UNSPEC,
+ SOCKET_INET,
+ SOCKET_IN6,
+ SOCKET_UNIX
+} SocketFamily;
+
+/* Generic socket address structure. Note that for Unix
+ * sockets, the path is stored in a heap-allocated block,
+ * unless the 'owner' field is cleared. If this is the case,
+ */
+typedef struct {
+ SocketFamily family;
+ union {
+ struct {
+ uint16_t port;
+ uint32_t address;
+ } inet;
+ struct {
+ uint16_t port;
+ uint8_t address[16];
+ } in6;
+ struct {
+ int owner;
+ const char* path;
+ } _unix;
+ } u;
+} SockAddress;
+
+#define SOCK_ADDRESS_INET_ANY 0x00000000
+#define SOCK_ADDRESS_INET_LOOPBACK 0x7f000001
+
+/* initialize a new IPv4 socket address, the IP address and port are
+ * in host endianess.
+ */
+void sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port );
+
+/* Initialize an IPv6 socket address, the address is in network order
+ * and the port in host endianess.
+ */
+#if HAVE_IN6_SOCKETS
+void sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port );
+#endif
+
+/* Intialize a Unix socket address, this will copy the 'path' string into the
+ * heap. You need to call sock_address_done() to release the copy
+ */
+#if HAVE_UNIX_SOCKETS
+void sock_address_init_unix( SockAddress* a, const char* path );
+#endif
+
+/* Finalize a socket address, only needed for now for Unix addresses */
+void sock_address_done( SockAddress* a );
+
+int sock_address_equal( const SockAddress* a, const SockAddress* b );
+
+/* return a static string describing the address */
+const char* sock_address_to_string( const SockAddress* a );
+
+static __inline__
+SocketFamily sock_address_get_family( const SockAddress* a )
+{
+ return a->family;
+}
+
+/* return the port number of a given socket address, or -1 if it's a Unix one */
+int sock_address_get_port( const SockAddress* a );
+
+/* set the port number of a given socket address, don't do anything for Unix ones */
+void sock_address_set_port( SockAddress* a, uint16_t port );
+
+/* return the path of a given Unix socket, returns NULL for non-Unix ones */
+const char* sock_address_get_path( const SockAddress* a );
+
+/* return the inet address, or -1 if it's not SOCKET_INET */
+int sock_address_get_ip( const SockAddress* a );
+
+/* bufprint a socket address into a human-readable string */
+char* bufprint_sock_address( char* p, char* end, const SockAddress* a );
+
+/* resolve a hostname or decimal IPv4/IPv6 address into a socket address.
+ * returns 0 on success, or -1 on failure. Note that the values or errno
+ * set by this function are the following:
+ *
+ * EINVAL : invalid argument
+ * EHOSTDOWN : could not reach DNS server
+ * ENOENT : no host with this name, or host doesn't have any IP address
+ * ENOMEM : not enough memory to perform request
+ */
+int sock_address_init_resolve( SockAddress* a,
+ const char* hostname,
+ uint16_t port,
+ int preferIn6 );
+
+int sock_address_get_numeric_info( SockAddress* a,
+ char* host,
+ size_t hostlen,
+ char* serv,
+ size_t servlen );
+
+/* Support for listing all socket addresses of a given host */
+enum {
+ SOCKET_LIST_PASSIVE = (1 << 0),
+ SOCKET_LIST_FORCE_INET = (1 << 1),
+ SOCKET_LIST_FORCE_IN6 = (1 << 2),
+ SOCKET_LIST_DGRAM = (1 << 3),
+};
+
+/* resolve a host and service/port name into a list of SockAddress objects.
+ * returns a NULL-terminated array of SockAddress pointers on success,
+ * or NULL in case of failure, with the value of errno set to one of the
+ * following:
+ *
+ * EINVAL : invalid argument
+ * EHOSTDOWN : could not reach DNS server
+ * ENOENT : no host with this name, or host doesn't have IP address
+ * ENOMEM : not enough memory to perform request
+ *
+ * other system-level errors can also be set depending on the host sockets
+ * implementation.
+ *
+ * This function loops on EINTR so the caller shouldn't have to check for it.
+ */
+SockAddress** sock_address_list_create( const char* hostname,
+ const char* port,
+ unsigned flags );
+
+/* resolve a string containing host and port name into a list of SockAddress
+ * objects. Parameter host_and_port should be in format [host:]port, where
+ * 'host' addresses the machine and must be resolvable into an IP address, and
+ * 'port' is a decimal numeric value for the port. 'host' is optional, and if
+ * ommited, localhost will be used.
+ * returns a NULL-terminated array of SockAddress pointers on success,
+ * or NULL in case of failure, with the value of errno set to one of the
+ * following:
+ *
+ * EINVAL : invalid argument
+ * EHOSTDOWN : could not reach DNS server
+ * ENOENT : no host with this name, or host doesn't have IP address
+ * ENOMEM : not enough memory to perform request
+ *
+ * other system-level errors can also be set depending on the host sockets
+ * implementation.
+ *
+ * This function loops on EINTR so the caller shouldn't have to check for it.
+ */
+SockAddress** sock_address_list_create2(const char* host_and_port,
+ unsigned flags );
+
+void sock_address_list_free( SockAddress** list );
+
+/* create a new socket, return the socket number of -1 on failure */
+int socket_create( SocketFamily family, SocketType type );
+
+/* create a new socket intended for IPv4 communication. returns the socket number,
+ * or -1 on failure.
+ */
+int socket_create_inet( SocketType type );
+
+/* create a new socket intended for IPv6 communication. returns the socket number,
+ * or -1 on failure.
+ */
+#if HAVE_IN6_SOCKETS
+int socket_create_in6 ( SocketType type );
+#endif
+
+/* create a unix/local domain socket. returns the socket number,
+ * or -1 on failure.
+ */
+#if HAVE_UNIX_SOCKETS
+int socket_create_unix( SocketType type );
+#endif
+
+/* return the type of a given socket */
+SocketType socket_get_type(int fd);
+
+/* set SO_REUSEADDR on Unix, SO_EXCLUSIVEADDR on Windows */
+int socket_set_xreuseaddr(int fd);
+
+/* set socket in non-blocking mode */
+int socket_set_nonblock(int fd);
+
+/* set socket in blocking mode */
+int socket_set_blocking(int fd);
+
+/* disable the TCP Nagle algorithm for lower latency */
+int socket_set_nodelay(int fd);
+
+/* send OOB data inline for this socket */
+int socket_set_oobinline(int fd);
+
+/* force listening to IPv6 interfaces only */
+int socket_set_ipv6only(int fd);
+
+/* retrieve last socket error code */
+int socket_get_error(int fd);
+
+/* close an opened socket. Note that this is unlike the Unix 'close' because:
+ * - it will properly shutdown the socket in the background
+ * - it does not modify errno
+ */
+void socket_close( int fd );
+
+/* the following functions are equivalent to the BSD sockets ones
+ */
+int socket_recv ( int fd, void* buf, int buflen );
+int socket_recvfrom( int fd, void* buf, int buflen, SockAddress* from );
+
+int socket_send ( int fd, const void* buf, int buflen );
+int socket_send_oob( int fd, const void* buf, int buflen );
+int socket_sendto( int fd, const void* buf, int buflen, const SockAddress* to );
+
+int socket_connect( int fd, const SockAddress* address );
+int socket_bind( int fd, const SockAddress* address );
+int socket_get_address( int fd, SockAddress* address );
+int socket_get_peer_address( int fd, SockAddress* address );
+int socket_listen( int fd, int backlog );
+int socket_accept( int fd, SockAddress* address );
+
+/* returns the number of bytes that can be read from a socket */
+int socket_can_read( int fd );
+
+/* this call creates a pair of non-blocking sockets connected
+ * to each other. this is equivalent to calling the Unix function:
+ * socketpair(AF_LOCAL,SOCK_STREAM,0,&fds)
+ *
+ * on Windows, this will use a pair of TCP loopback sockets instead
+ * returns 0 on success, -1 on error.
+ */
+int socket_pair(int *fd1, int *fd2);
+
+/* create a server socket listening on the host's loopback interface */
+int socket_loopback_server( int port, SocketType type );
+
+/* connect to a port on the host's loopback interface */
+int socket_loopback_client( int port, SocketType type );
+
+/* create a server socket listening to a Unix domain path */
+#if HAVE_UNIX_SOCKETS
+int socket_unix_server( const char* name, SocketType type );
+#endif
+
+/* create a Unix sockets and connects it to a Unix server */
+#if HAVE_UNIX_SOCKETS
+int socket_unix_client( const char* name, SocketType type );
+#endif
+
+/* create an IPv4 client socket and connect it to a given host */
+int socket_network_client( const char* host, int port, SocketType type );
+
+/* create an IPv4 socket and binds it to a given port of the host's interface */
+int socket_anyaddr_server( int port, SocketType type );
+
+/* accept a connection from the host's any interface, return the new socket
+ * descriptor or -1 */
+int socket_accept_any( int server_fd );
+
+
+int socket_mcast_inet_add_membership( int s, uint32_t ip );
+int socket_mcast_inet_drop_membership( int s, uint32_t ip );
+int socket_mcast_inet_set_loop( int s, int enabled );
+int socket_mcast_inet_set_ttl( int s, int ttl );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ANDROID_SOCKET_H */
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk b/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk
new file mode 100644
index 0000000..f7c8fed
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk
@@ -0,0 +1,80 @@
+LOCAL_PATH := $(call my-dir)
+
+#### libGLESv1_CM_emul.so
+$(call emugl-begin-shared-library,libGLESv1_CM_emul)
+$(call emugl-import,libGLESv1_enc)
+$(call emugl-gen-wrapper,$(EMUGL_PATH)/system/GLESv1_enc,gl)
+$(call emugl-set-shared-library-subpath,egl)
+
+LOCAL_SRC_FILES += glesv1_emul_ifc.cpp
+
+$(call emugl-end-module)
+
+emulatorOpengl := $(LOCAL_PATH)/../..
+logTag := -DLOG_TAG=\"eglWrapper\"
+EMUGEN = $(BUILD_OUT_EXECUTABLES)/emugen
+## comment for no debug
+#debugFlags = -g -O0
+
+#### libGLESv2_CM_emul.so
+$(call emugl-begin-shared-library, libGLESv2_emul)
+$(call emugl-import,libGLESv2_enc)
+$(call emugl-gen-wrapper,$(EMUGL_PATH)/system/GLESv2_enc,gl2)
+LOCAL_SRC_FILES += glesv2_emul_ifc.cpp
+$(call emugl-set-shared-library-subpath,egl)
+$(call emugl-end-module)
+
+##### libEGL_emul.so ###########
+
+# THE FOLLOWING DOESN'T WORK YET
+#
+$(call emugl-begin-shared-library,libEGL_emul)
+$(call emugl-import,libut_rendercontrol_enc libGLESv1_CM_emul libGLESv2_emul libOpenglSystemCommon)
+
+$(call emugl-set-shared-library-subpath,egl)
+LOCAL_CFLAGS += $(logTag)
+
+LOCAL_SRC_FILES := \
+ egl.cpp \
+ egl_dispatch.cpp \
+ ServerConnection.cpp \
+ ThreadInfo.cpp
+
+$(call emugl-end-module)
+
+#### egl.cfg ####
+
+# Ensure that this file is only copied to emulator-specific builds.
+# Other builds are device-specific and will provide their own
+# version of this file to point to the appropriate HW EGL libraries.
+#
+ifneq (,$(filter full full_x86 sdk sdk_x86,$(TARGET_PRODUCT)))
+ifeq (,$(BUILD_EMULATOR_OPENGL_DRIVER))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := egl.cfg
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_PREBUILT)
+endif # building 'real' driver BUILD_EMULATOR_OPENGL_DRIVER
+endif # TARGET_PRODUCT in 'full sdk full_x86 sdk_x86'
+
+#### gles_emul.cfg ####
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := gles_emul.cfg
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_PREBUILT)
+
+
+
+
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ApiInitializer.h b/tools/emulator/opengl/tests/gles_android_wrapper/ApiInitializer.h
new file mode 100644
index 0000000..7dc5006
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/ApiInitializer.h
@@ -0,0 +1,26 @@
+#ifndef _API_INITIALIZER_H_
+#define _API_INITIALIZER_H_
+#include <stdlib.h>
+#include <dlfcn.h>
+
+class ApiInitializer {
+public:
+ ApiInitializer(void *dso) :
+ m_dso(dso) {
+ }
+ static void *s_getProc(const char *name, void *userData) {
+ ApiInitializer *self = (ApiInitializer *)userData;
+ return self->getProc(name);
+ }
+private:
+ void *m_dso;
+ void *getProc(const char *name) {
+ void *symbol = NULL;
+ if (m_dso) {
+ symbol = dlsym(m_dso, name);
+ }
+ return symbol;
+ }
+};
+
+#endif
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/CleanSpec.mk b/tools/emulator/opengl/tests/gles_android_wrapper/CleanSpec.mk
new file mode 100644
index 0000000..f56383a
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/CleanSpec.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2007 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/SHARED_LIBRARIES/libGLES_emul_intermediates)
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp
new file mode 100644
index 0000000..1204264
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp
@@ -0,0 +1,125 @@
+/*
+* 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include "ServerConnection.h"
+#include "TcpStream.h"
+#include "QemuPipeStream.h"
+#include <cutils/log.h>
+#include "ThreadInfo.h"
+
+gl_client_context_t *ServerConnection::s_getGlContext()
+{
+ EGLThreadInfo *ti = getEGLThreadInfo();
+ if (ti->serverConn) {
+ return ti->serverConn->m_glEnc;
+ }
+ return NULL;
+}
+
+gl2_client_context_t *ServerConnection::s_getGl2Context()
+{
+ EGLThreadInfo *ti = getEGLThreadInfo();
+ if (ti->serverConn) {
+ return ti->serverConn->m_gl2Enc;
+ }
+ return NULL;
+}
+
+ServerConnection *ServerConnection::s_getServerConnection()
+{
+ EGLThreadInfo *ti = getEGLThreadInfo();
+ if (!ti->serverConn)
+ {
+ ti->serverConn = new ServerConnection();
+ if (ti->serverConn->create() < 0) {
+ delete ti->serverConn;
+ ti->serverConn = NULL;
+ }
+ }
+
+ return ti->serverConn;
+}
+
+
+ServerConnection::ServerConnection() :
+ m_stream(NULL),
+ m_glEnc(NULL),
+ m_ut_enc(NULL)
+{
+}
+
+ServerConnection::~ServerConnection()
+{
+ delete m_ut_enc;
+ delete m_glEnc;
+ delete m_stream;
+}
+
+
+
+int ServerConnection::create(size_t bufsize,
+ const char *defaultServer)
+{
+ /* XXX: Make configurable through system property */
+ int useQemuPipe = 1;
+
+ if (m_stream != NULL) delete(m_stream);
+
+ if (useQemuPipe) {
+ QemuPipeStream* pipeStream = new QemuPipeStream(bufsize);
+
+ if (pipeStream->connect() < 0) {
+ LOGE("couldn't connect to host server\n");
+ delete pipeStream;
+ return -1;
+ }
+ m_stream = pipeStream;
+ }
+ else /* !useQemuPipe */
+ {
+ TcpStream* tcpStream = new TcpStream(bufsize);
+
+ char *s = getenv(ENV_RGL_SERVER);
+ char *hostname;
+ if (s == NULL) {
+ hostname = strdup(defaultServer);
+ } else {
+ hostname = strdup(s);
+ }
+
+ if (tcpStream->connect(hostname, CODEC_SERVER_PORT) < 0) {
+ LOGE("couldn't connect to %s\n", hostname);
+ free(hostname);
+ delete tcpStream;
+ return -1;
+ }
+ LOGI("connecting to server %s\n", hostname);
+ free(hostname);
+
+ m_stream = tcpStream;
+ }
+
+ m_glEnc = new GLEncoder(m_stream);
+ m_glEnc->setContextAccessor(s_getGlContext);
+
+ m_gl2Enc = new GL2Encoder(m_stream);
+ m_gl2Enc->setContextAccessor(s_getGl2Context);
+
+ m_ut_enc = new ut_rendercontrol_encoder_context_t(m_stream);
+ return 0;
+}
+
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h
new file mode 100644
index 0000000..84f40d8
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h
@@ -0,0 +1,55 @@
+/*
+* 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.
+*/
+#ifndef _SERVER_CONNECTION_H
+#define _SERVER_CONNECTION_H
+
+#include "GLEncoder.h"
+#include "GL2Encoder.h"
+#include "IOStream.h"
+#include "codec_defs.h"
+#include "ut_rendercontrol_enc.h"
+#include <pthread.h>
+
+#define ENV_RGL_SERVER "RGL_SERVER"
+#define RGL_DEFAULT_SERVER "10.0.2.2"
+
+class ServerConnection {
+public:
+ ~ServerConnection();
+ int create(size_t buf_size = 4 * 1024 * 1024, const char *defaultServer = RGL_DEFAULT_SERVER);
+ static gl_client_context_t *s_getGlContext();
+ static ServerConnection *s_getServerConnection();
+ static gl2_client_context_t *s_getGl2Context();
+ GLEncoder *glEncoder() { return m_glEnc; }
+ GL2Encoder *gl2Encoder() { return m_gl2Enc; }
+ ut_rendercontrol_encoder_context_t * utEnc() { return m_ut_enc; }
+
+private:
+ ServerConnection();
+
+private:
+ static pthread_key_t s_glKey;
+ static pthread_key_t s_connectionKey;
+ static void s_initKeys();
+ IOStream *m_stream;
+ GLEncoder *m_glEnc;
+ GL2Encoder *m_gl2Enc;
+ ut_rendercontrol_encoder_context_t *m_ut_enc;
+
+};
+
+
+#endif
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.cpp
new file mode 100644
index 0000000..5bf6a7d
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.cpp
@@ -0,0 +1,39 @@
+/*
+* 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.
+*/
+#include "ThreadInfo.h"
+#include "cutils/threads.h"
+
+thread_store_t s_tls = THREAD_STORE_INITIALIZER;
+
+static void tlsDestruct(void *ptr)
+{
+ if (ptr) {
+ EGLThreadInfo *ti = (EGLThreadInfo *)ptr;
+ delete ti->serverConn;
+ delete ti;
+ }
+}
+
+EGLThreadInfo *getEGLThreadInfo()
+{
+ EGLThreadInfo *ti = (EGLThreadInfo *)thread_store_get(&s_tls);
+ if (ti) return ti;
+
+ ti = new EGLThreadInfo();
+ thread_store_set(&s_tls, ti, tlsDestruct);
+
+ return ti;
+}
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.h b/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.h
new file mode 100644
index 0000000..f748a39
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/ThreadInfo.h
@@ -0,0 +1,49 @@
+/*
+* 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.
+*/
+#ifndef _THREAD_INFO_H
+#define _THREAD_INFO_H
+
+#include "ServerConnection.h"
+#include <EGL/egl.h>
+
+struct EGLWrapperContext
+{
+ EGLWrapperContext(EGLContext p_aglContext, int _version) {
+ aglContext = p_aglContext;
+ clientState = NULL;
+ version = _version;
+ }
+
+ ~EGLWrapperContext() {
+ delete clientState;
+ }
+
+ EGLContext aglContext;
+ GLClientState *clientState;
+ int version;
+};
+
+struct EGLThreadInfo
+{
+ EGLThreadInfo() : currentContext(NULL), serverConn(NULL) {}
+
+ EGLWrapperContext *currentContext;
+ ServerConnection *serverConn;
+};
+
+
+EGLThreadInfo *getEGLThreadInfo();
+#endif
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cfg b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cfg
new file mode 100644
index 0000000..891b07d
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cfg
@@ -0,0 +1 @@
+0 0 emul
\ No newline at end of file
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp
new file mode 100644
index 0000000..1ee2b6a
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl.cpp
@@ -0,0 +1,663 @@
+/*
+* 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.
+*/
+
+//
+// WARNING -------------------------- WARNING
+// This code meant to be used for testing purposes only. It is not production
+// level quality.
+// Use on your own risk !!
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include "egl_dispatch.h"
+#include "egl_ftable.h"
+#include <cutils/process_name.h>
+#include <cutils/log.h>
+#include "ServerConnection.h"
+#include "ThreadInfo.h"
+#include <pthread.h>
+#include "gl_wrapper_context.h"
+#include "gl2_wrapper_context.h"
+
+#define GLES_EMUL_TARGETS_FILE "/system/etc/gles_emul.cfg"
+// implementation libraries;
+#define GLESv1_enc_LIB "/system/lib/libGLESv1_enc.so"
+#define GLESv2_enc_LIB "/system/lib/libGLESv2_enc.so"
+#define GLES_android_LIB "/system/lib/egl/libGLES_android.so"
+// driver libraries;
+#define GLESv1_DRIVER "/system/lib/egl/libGLESv1_CM_emul.so"
+#define GLESv2_DRIVER "/system/lib/egl/libGLESv2_emul.so"
+
+
+static struct egl_dispatch *s_dispatch = NULL;
+pthread_once_t dispatchTablesInitialized = PTHREAD_ONCE_INIT;
+
+static bool s_needEncode = false;
+
+static gl_wrapper_context_t *g_gl_dispatch = NULL;
+static gl2_wrapper_context_t *g_gl2_dispatch = NULL;
+
+template <class T>
+int initApi(const char *driverLibName, const char *implLibName, T **dispatchTable, T *(*accessor)())
+{
+ void *driverLib = dlopen(driverLibName, RTLD_NOW | RTLD_LOCAL);
+ if (driverLib == NULL) {
+ LOGE("failed to load %s : %s\n", driverLibName, dlerror());
+ return -1;
+ }
+
+ typedef T *(*createFcn_t)(void *, T *(*accessor)());
+ createFcn_t createFcn;
+ createFcn = (createFcn_t) dlsym(driverLib, "createFromLib");
+ if (createFcn == NULL) {
+ LOGE("failed to load createFromLib constructor function\n");
+ return -1;
+ }
+
+ void *implLib = dlopen(implLibName, RTLD_NOW | RTLD_LOCAL);
+ if (implLib == NULL) {
+ LOGE("couldn't open %s", implLibName);
+ return -2;
+ }
+ *dispatchTable = createFcn(implLib, accessor);
+ if (*dispatchTable == NULL) {
+ return -3;
+ }
+
+ // XXX - we do close the impl library since it doesn't have data, as far as we concern.
+ dlclose(implLib);
+
+ // XXX - we do not dlclose the driver library, so its not initialized when
+ // later loaded by android - is this required?
+ LOGD("loading %s into %s complete\n", implLibName, driverLibName);
+ return 0;
+
+}
+
+static gl_wrapper_context_t *getGLContext()
+{
+ return g_gl_dispatch;
+}
+
+static gl2_wrapper_context_t *getGL2Context()
+{
+ return g_gl2_dispatch;
+}
+
+const char *getProcName()
+{
+ static const char *procname = NULL;
+
+ if (procname == NULL) {
+ const char *str = get_process_name();
+ if (strcmp(str, "unknown") != 0) {
+ procname = str;
+ } else {
+ // we need to obtain our process name from the command line;
+ FILE *fp = fopen("/proc/self/cmdline", "rt");
+ if (fp == NULL) {
+ LOGE("couldn't open /proc/self/cmdline\n");
+ return NULL;
+ }
+
+ char line[1000];
+ if (fgets(line, sizeof(line), fp) == NULL) {
+ LOGE("couldn't read the self cmdline from \n");
+ fclose(fp);
+ return NULL;
+ }
+ fclose(fp);
+
+ if (line[0] == '\0') {
+ LOGE("cmdline is empty\n");
+ return NULL;
+ }
+
+ //obtain the basename;
+ line[sizeof(line) - 1] = '\0';
+ char *p = line;
+ while (*p != '\0' &&
+ *p != '\t' &&
+ *p != ' ' &&
+ *p != '\n') {
+ p++;
+ }
+
+ *p = '\0'; p--;
+ while (p > line && *p != '/') p--;
+ if (*p == '/') p++;
+ procname = strdup(p);
+ }
+ }
+
+ return procname;
+}
+
+
+
+bool isNeedEncode()
+{
+ const char *procname = getProcName();
+ if (procname == NULL) return false;
+ LOGD("isNeedEncode? for %s\n", procname);
+ // check on our whitelist
+ FILE *fp = fopen(GLES_EMUL_TARGETS_FILE, "rt");
+ if (fp == NULL) {
+ LOGE("couldn't open %s\n", GLES_EMUL_TARGETS_FILE);
+ return false;
+ }
+
+ char line[100];
+ bool found = false;
+ size_t procnameLen = strlen(procname);
+
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ if (strlen(line) >= procnameLen &&
+ !strncmp(procname, line, procnameLen)) {
+ char c = line[procnameLen];
+ if (c == '\0' || c == ' ' || c == '\t' || c == '\n') {
+ found = true;
+ LOGD("should use encoder for %s\n", procname);
+ break;
+ }
+ }
+ }
+ fclose(fp);
+ return found;
+}
+
+void initDispatchTables()
+{
+ //
+ // Load our back-end implementation of EGL/GLES
+ //
+ LOGD("Loading egl dispatch for %s\n", getProcName());
+
+ void *gles_android = dlopen("/system/lib/egl/libGLES_android.so", RTLD_NOW | RTLD_LOCAL);
+ if (!gles_android) {
+ fprintf(stderr,"FATAL ERROR: Could not load libGLES_android lib\n");
+ exit(-1);
+ }
+
+ //
+ // Load back-end EGL implementation library
+ //
+ s_dispatch = create_egl_dispatch( gles_android );
+ if (!s_dispatch) {
+ fprintf(stderr,"FATAL ERROR: Could not create egl dispatch\n");
+ exit(-1);
+ }
+
+ //
+ // initialize gles
+ //
+ s_needEncode = isNeedEncode();
+ void *gles_encoder = NULL;
+ if (s_needEncode) {
+ // initialize a connection to the server, and the GLESv1/v2 encoders;
+ ServerConnection * connection = ServerConnection::s_getServerConnection();
+ if (connection == NULL) {
+ LOGE("couldn't create server connection\n");
+ s_needEncode = false;
+ }
+ }
+
+ // init dispatch tabels for GLESv1 & GLESv2
+ if (s_needEncode) {
+ // XXX - we do not check the retrun value because there isn't much we can do here on failure.
+
+ if (initApi<gl_wrapper_context_t>(GLESv1_DRIVER, GLESv1_enc_LIB, &g_gl_dispatch, getGLContext) < 0) {
+ // fallback to android on faluire
+ s_needEncode = false;
+ } else {
+ initApi<gl2_wrapper_context_t>(GLESv2_DRIVER, GLESv2_enc_LIB, &g_gl2_dispatch, getGL2Context);
+ }
+ }
+
+ if (!s_needEncode) {
+ LOGD("Initializing native opengl for %s\n", getProcName());
+ initApi<gl_wrapper_context_t>(GLESv1_DRIVER, GLES_android_LIB, &g_gl_dispatch, getGLContext);
+ // try to initialize gl2 from GLES, though its probably going to fail
+ initApi<gl2_wrapper_context_t>(GLESv2_DRIVER, GLES_android_LIB, &g_gl2_dispatch, getGL2Context);
+ }
+}
+
+static struct egl_dispatch *getDispatch()
+{
+ pthread_once(&dispatchTablesInitialized, initDispatchTables);
+ return s_dispatch;
+}
+
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
+{
+
+ // search in EGL function table
+ for (int i=0; i<egl_num_funcs; i++) {
+ if (!strcmp(egl_funcs_by_name[i].name, procname)) {
+ return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
+ }
+ }
+
+ // we do not support eglGetProcAddress for GLESv1 & GLESv2. The loader
+ // should be able to find this function through dynamic loading.
+ return NULL;
+}
+
+//////////////// Path through functions //////////
+
+EGLint eglGetError()
+{
+ return getDispatch()->eglGetError();
+}
+
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
+{
+ return getDispatch()->eglGetDisplay(display_id);
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ return getDispatch()->eglInitialize(dpy, major, minor);
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+ return getDispatch()->eglTerminate(dpy);
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+ return getDispatch()->eglQueryString(dpy, name);
+}
+
+EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ return getDispatch()->eglGetConfigs(dpy, configs, config_size, num_config);
+}
+
+static EGLint * filter_es2_bit(const EGLint *attrib_list, bool *isES2)
+{
+ if (attrib_list == NULL) {
+ if (isES2 != NULL) *isES2 = false;
+ return NULL;
+ }
+
+ EGLint *attribs = NULL;
+ int nAttribs = 0;
+ while(attrib_list[nAttribs] != EGL_NONE) nAttribs++;
+ nAttribs++;
+
+ attribs = new EGLint[nAttribs];
+ memcpy(attribs, attrib_list, nAttribs * sizeof(EGLint));
+ if (isES2 != NULL) *isES2 = false;
+
+ // scan the attribute list for ES2 request and replace with ES1.
+ for (int i = 0; i < nAttribs; i++) {
+ if (attribs[i] == EGL_RENDERABLE_TYPE) {
+ if (attribs[i + 1] & EGL_OPENGL_ES2_BIT) {
+ attribs[i + 1] &= ~EGL_OPENGL_ES2_BIT;
+ attribs[i + 1] |= EGL_OPENGL_ES_BIT;
+ LOGD("removing ES2 bit 0x%x\n", attribs[i + 1]);
+ if (isES2 != NULL) *isES2 = true;
+ }
+ }
+ }
+ return attribs;
+}
+
+EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ EGLBoolean res;
+ if (s_needEncode) {
+ EGLint *attribs = filter_es2_bit(attrib_list, NULL);
+ res = getDispatch()->eglChooseConfig(dpy,
+ attribs,
+ configs,
+ config_size,
+ num_config);
+ LOGD("eglChooseConfig: %d configs found\n", *num_config);
+ if (*num_config == 0 && attribs != NULL) {
+ LOGD("requested attributes:\n");
+ for (int i = 0; attribs[i] != EGL_NONE; i++) {
+ LOGD("%d: 0x%x\n", i, attribs[i]);
+ }
+ }
+
+ delete attribs;
+ } else {
+ res = getDispatch()->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+ }
+ return res;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+ if (s_needEncode && attribute == EGL_RENDERABLE_TYPE) {
+ *value = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
+ return EGL_TRUE;
+ } else {
+ return getDispatch()->eglGetConfigAttrib(dpy, config, attribute, value);
+ }
+}
+
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+ EGLSurface surface = getDispatch()->eglCreateWindowSurface(dpy, config, win, attrib_list);
+ if (surface != EGL_NO_SURFACE) {
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+ server->utEnc()->createSurface(server->utEnc(), getpid(), (uint32_t)surface);
+ }
+ }
+ return surface;
+}
+
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+ EGLSurface surface = getDispatch()->eglCreatePbufferSurface(dpy, config, attrib_list);
+ if (surface != EGL_NO_SURFACE) {
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+ server->utEnc()->createSurface(server->utEnc(), getpid(), (uint32_t)surface);
+ }
+ }
+ return surface;
+}
+
+EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+ EGLSurface surface = getDispatch()->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);
+ if (surface != EGL_NO_SURFACE) {
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+ server->utEnc()->createSurface(server->utEnc(), getpid(), (uint32_t)surface);
+ }
+ }
+ return surface;
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ EGLBoolean res = getDispatch()->eglDestroySurface(dpy, surface);
+ if (res && surface != EGL_NO_SURFACE) {
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+ server->utEnc()->destroySurface(server->utEnc(), getpid(), (uint32_t)surface);
+ }
+ }
+ return res;
+}
+
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+ EGLBoolean res = getDispatch()->eglQuerySurface(dpy, surface, attribute, value);
+ if (res && attribute == EGL_RENDERABLE_TYPE) {
+ *value |= EGL_OPENGL_ES2_BIT;
+ }
+ return res;
+}
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+ return getDispatch()->eglBindAPI(api);
+}
+
+EGLenum eglQueryAPI()
+{
+ return getDispatch()->eglQueryAPI();
+}
+
+EGLBoolean eglWaitClient()
+{
+ return getDispatch()->eglWaitClient();
+}
+
+EGLBoolean eglReleaseThread()
+{
+ return getDispatch()->eglReleaseThread();
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+ return getDispatch()->eglSurfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ return getDispatch()->eglBindTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ return getDispatch()->eglReleaseTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ return getDispatch()->eglSwapInterval(dpy, interval);
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+
+ EGLContext share = share_context;
+ if (share) share = ((EGLWrapperContext *)share_context)->aglContext;
+
+ // check if are ES2, and convert it to ES1.
+ int nAttribs = 0;
+ if (attrib_list != NULL) {
+ while(attrib_list[nAttribs] != EGL_NONE) {
+ nAttribs++;
+ }
+ nAttribs++;
+ }
+
+ EGLint *attrib = NULL;
+ if (nAttribs > 0) {
+ attrib = new EGLint[nAttribs];
+ memcpy(attrib, attrib_list, nAttribs * sizeof(EGLint));
+ }
+
+ int version = 1;
+ for (int i = 0; i < nAttribs; i++) {
+ if (attrib[i] == EGL_CONTEXT_CLIENT_VERSION &&
+ attrib[i + 1] == 2) {
+ version = 2;
+ attrib[i + 1] = 1; // replace to version 1
+ }
+ }
+
+ EGLContext ctx = getDispatch()->eglCreateContext(dpy, config, share, attrib);
+ delete attrib;
+ EGLWrapperContext *wctx = new EGLWrapperContext(ctx, version);
+ if (ctx != EGL_NO_CONTEXT) {
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+ wctx->clientState = new GLClientState();
+ server->utEnc()->createContext(server->utEnc(), getpid(),
+ (uint32_t)wctx,
+ (uint32_t)(share_context == EGL_NO_CONTEXT ? 0 : share_context), wctx->version);
+ }
+ }
+ return (EGLContext)wctx;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+ EGLBoolean res = EGL_FALSE;
+
+ if (ctx && ctx != EGL_NO_CONTEXT) {
+ res = getDispatch()->eglDestroyContext(dpy, wctx->aglContext);
+ if (res) {
+ EGLThreadInfo *ti = getEGLThreadInfo();
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection())) {
+ server->utEnc()->destroyContext(ti->serverConn->utEnc(), getpid(), (uint32_t)ctx);
+ }
+ if (ti->currentContext == wctx) ti->currentContext = NULL;
+ delete wctx;
+ }
+ }
+
+ return res;
+}
+
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+ EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+ EGLContext aglContext = (ctx == EGL_NO_CONTEXT ? EGL_NO_CONTEXT : wctx->aglContext);
+ EGLThreadInfo *ti = getEGLThreadInfo();
+ EGLBoolean res = getDispatch()->eglMakeCurrent(dpy, draw, read, aglContext);
+ if (res ) {
+ // NOTE - we do get a pointer to the server connection, (rather then using ti->serverConn)
+ // for cases that this is the first egl call of the current thread.
+
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection())) {
+ server->utEnc()->makeCurrentContext(server->utEnc(), getpid(),
+ (uint32_t) (draw == EGL_NO_SURFACE ? 0 : draw),
+ (uint32_t) (read == EGL_NO_SURFACE ? 0 : read),
+ (uint32_t) (ctx == EGL_NO_CONTEXT ? 0 : ctx));
+ server->glEncoder()->setClientState( wctx ? wctx->clientState : NULL );
+ server->gl2Encoder()->setClientState( wctx ? wctx->clientState : NULL );
+ }
+
+ // set current context in our thread info
+ ti->currentContext = wctx;
+ }
+ return res;
+
+}
+
+EGLContext eglGetCurrentContext()
+{
+ EGLThreadInfo *ti = getEGLThreadInfo();
+ return (ti->currentContext ? ti->currentContext : EGL_NO_CONTEXT);
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+ return getDispatch()->eglGetCurrentSurface(readdraw);
+}
+
+EGLDisplay eglGetCurrentDisplay()
+{
+ return getDispatch()->eglGetCurrentDisplay();
+}
+
+EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+ EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+ if (wctx) {
+ if (attribute == EGL_CONTEXT_CLIENT_VERSION) {
+ *value = wctx->version;
+ return EGL_TRUE;
+ } else {
+ return getDispatch()->eglQueryContext(dpy, wctx->aglContext, attribute, value);
+ }
+ }
+ else {
+ return EGL_BAD_CONTEXT;
+ }
+}
+
+EGLBoolean eglWaitGL()
+{
+ return getDispatch()->eglWaitGL();
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+ return getDispatch()->eglWaitNative(engine);
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ ServerConnection *server;
+ if (s_needEncode && (server = ServerConnection::s_getServerConnection()) != NULL) {
+ server->utEnc()->swapBuffers(server->utEnc(), getpid(), (uint32_t)surface);
+ server->glEncoder()->flush();
+ server->gl2Encoder()->flush();
+ return 1;
+ }
+ return getDispatch()->eglSwapBuffers(dpy, surface);
+}
+
+EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+ return getDispatch()->eglCopyBuffers(dpy, surface, target);
+}
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
+{
+ return getDispatch()->eglLockSurfaceKHR(display, surface, attrib_list);
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
+{
+ return getDispatch()->eglUnlockSurfaceKHR(display, surface);
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+ EGLWrapperContext *wctx = (EGLWrapperContext *)ctx;
+ EGLContext aglContext = (wctx ? wctx->aglContext : EGL_NO_CONTEXT);
+ return getDispatch()->eglCreateImageKHR(dpy, aglContext, target, buffer, attrib_list);
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+ return getDispatch()->eglDestroyImageKHR(dpy, image);
+}
+
+EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+ return getDispatch()->eglCreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ return getDispatch()->eglDestroySyncKHR(dpy, sync);
+}
+
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+{
+ return getDispatch()->eglClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+{
+ return getDispatch()->eglSignalSyncKHR(dpy, sync, mode);
+}
+
+EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+{
+ return getDispatch()->eglGetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height)
+{
+ return getDispatch()->eglSetSwapRectangleANDROID(dpy, draw, left, top, width, height);
+}
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl_dispatch.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/egl_dispatch.cpp
new file mode 100644
index 0000000..f69ca61
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl_dispatch.cpp
@@ -0,0 +1,71 @@
+/*
+* 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.
+*/
+#include <stdio.h>
+#include "egl_dispatch.h"
+#include <dlfcn.h>
+
+egl_dispatch *create_egl_dispatch(void *gles_android)
+{
+ egl_dispatch *disp = new egl_dispatch;
+
+ void *ptr;
+ ptr = dlsym(gles_android,"eglGetError"); disp->set_eglGetError((eglGetError_t)ptr);
+ ptr = dlsym(gles_android,"eglGetDisplay"); disp->set_eglGetDisplay((eglGetDisplay_t)ptr);
+ ptr = dlsym(gles_android,"eglInitialize"); disp->set_eglInitialize((eglInitialize_t)ptr);
+ ptr = dlsym(gles_android,"eglTerminate"); disp->set_eglTerminate((eglTerminate_t)ptr);
+ ptr = dlsym(gles_android,"eglQueryString"); disp->set_eglQueryString((eglQueryString_t)ptr);
+ ptr = dlsym(gles_android,"eglGetConfigs"); disp->set_eglGetConfigs((eglGetConfigs_t)ptr);
+ ptr = dlsym(gles_android,"eglChooseConfig"); disp->set_eglChooseConfig((eglChooseConfig_t)ptr);
+ ptr = dlsym(gles_android,"eglGetConfigAttrib"); disp->set_eglGetConfigAttrib((eglGetConfigAttrib_t)ptr);
+ ptr = dlsym(gles_android,"eglCreateWindowSurface"); disp->set_eglCreateWindowSurface((eglCreateWindowSurface_t)ptr);
+ ptr = dlsym(gles_android,"eglCreatePbufferSurface"); disp->set_eglCreatePbufferSurface((eglCreatePbufferSurface_t)ptr);
+ ptr = dlsym(gles_android,"eglCreatePixmapSurface"); disp->set_eglCreatePixmapSurface((eglCreatePixmapSurface_t)ptr);
+ ptr = dlsym(gles_android,"eglDestroySurface"); disp->set_eglDestroySurface((eglDestroySurface_t)ptr);
+ ptr = dlsym(gles_android,"eglQuerySurface"); disp->set_eglQuerySurface((eglQuerySurface_t)ptr);
+ ptr = dlsym(gles_android,"eglBindAPI"); disp->set_eglBindAPI((eglBindAPI_t)ptr);
+ ptr = dlsym(gles_android,"eglQueryAPI"); disp->set_eglQueryAPI((eglQueryAPI_t)ptr);
+ ptr = dlsym(gles_android,"eglWaitClient"); disp->set_eglWaitClient((eglWaitClient_t)ptr);
+ ptr = dlsym(gles_android,"eglReleaseThread"); disp->set_eglReleaseThread((eglReleaseThread_t)ptr);
+ ptr = dlsym(gles_android,"eglCreatePbufferFromClientBuffer"); disp->set_eglCreatePbufferFromClientBuffer((eglCreatePbufferFromClientBuffer_t)ptr);
+ ptr = dlsym(gles_android,"eglSurfaceAttrib"); disp->set_eglSurfaceAttrib((eglSurfaceAttrib_t)ptr);
+ ptr = dlsym(gles_android,"eglBindTexImage"); disp->set_eglBindTexImage((eglBindTexImage_t)ptr);
+ ptr = dlsym(gles_android,"eglReleaseTexImage"); disp->set_eglReleaseTexImage((eglReleaseTexImage_t)ptr);
+ ptr = dlsym(gles_android,"eglSwapInterval"); disp->set_eglSwapInterval((eglSwapInterval_t)ptr);
+ ptr = dlsym(gles_android,"eglCreateContext"); disp->set_eglCreateContext((eglCreateContext_t)ptr);
+ ptr = dlsym(gles_android,"eglDestroyContext"); disp->set_eglDestroyContext((eglDestroyContext_t)ptr);
+ ptr = dlsym(gles_android,"eglMakeCurrent"); disp->set_eglMakeCurrent((eglMakeCurrent_t)ptr);
+ ptr = dlsym(gles_android,"eglGetCurrentContext"); disp->set_eglGetCurrentContext((eglGetCurrentContext_t)ptr);
+ ptr = dlsym(gles_android,"eglGetCurrentSurface"); disp->set_eglGetCurrentSurface((eglGetCurrentSurface_t)ptr);
+ ptr = dlsym(gles_android,"eglGetCurrentDisplay"); disp->set_eglGetCurrentDisplay((eglGetCurrentDisplay_t)ptr);
+ ptr = dlsym(gles_android,"eglQueryContext"); disp->set_eglQueryContext((eglQueryContext_t)ptr);
+ ptr = dlsym(gles_android,"eglWaitGL"); disp->set_eglWaitGL((eglWaitGL_t)ptr);
+ ptr = dlsym(gles_android,"eglWaitNative"); disp->set_eglWaitNative((eglWaitNative_t)ptr);
+ ptr = dlsym(gles_android,"eglSwapBuffers"); disp->set_eglSwapBuffers((eglSwapBuffers_t)ptr);
+ ptr = dlsym(gles_android,"eglCopyBuffers"); disp->set_eglCopyBuffers((eglCopyBuffers_t)ptr);
+ ptr = dlsym(gles_android,"eglGetProcAddress"); disp->set_eglGetProcAddress((eglGetProcAddress_t)ptr);
+ ptr = dlsym(gles_android,"eglLockSurfaceKHR"); disp->set_eglLockSurfaceKHR((eglLockSurfaceKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglUnlockSurfaceKHR"); disp->set_eglUnlockSurfaceKHR((eglUnlockSurfaceKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglCreateImageKHR"); disp->set_eglCreateImageKHR((eglCreateImageKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglDestroyImageKHR"); disp->set_eglDestroyImageKHR((eglDestroyImageKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglCreateSyncKHR"); disp->set_eglCreateSyncKHR((eglCreateSyncKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglDestroySyncKHR"); disp->set_eglDestroySyncKHR((eglDestroySyncKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglClientWaitSyncKHR"); disp->set_eglClientWaitSyncKHR((eglClientWaitSyncKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglSignalSyncKHR"); disp->set_eglSignalSyncKHR((eglSignalSyncKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglGetSyncAttribKHR"); disp->set_eglGetSyncAttribKHR((eglGetSyncAttribKHR_t)ptr);
+ ptr = dlsym(gles_android,"eglSetSwapRectangleANDROID"); disp->set_eglSetSwapRectangleANDROID((eglSetSwapRectangleANDROID_t)ptr);
+
+ return disp;
+}
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl_dispatch.h b/tools/emulator/opengl/tests/gles_android_wrapper/egl_dispatch.h
new file mode 100644
index 0000000..1b8de0d
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl_dispatch.h
@@ -0,0 +1,115 @@
+/*
+* 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.
+*/
+#ifndef _EGL_DISPATCH_H
+#define _EGL_DISPATCH_H
+
+#include "egl_proc.h"
+
+struct egl_dispatch {
+ eglGetError_t eglGetError;
+ eglGetDisplay_t eglGetDisplay;
+ eglInitialize_t eglInitialize;
+ eglTerminate_t eglTerminate;
+ eglQueryString_t eglQueryString;
+ eglGetConfigs_t eglGetConfigs;
+ eglChooseConfig_t eglChooseConfig;
+ eglGetConfigAttrib_t eglGetConfigAttrib;
+ eglCreateWindowSurface_t eglCreateWindowSurface;
+ eglCreatePbufferSurface_t eglCreatePbufferSurface;
+ eglCreatePixmapSurface_t eglCreatePixmapSurface;
+ eglDestroySurface_t eglDestroySurface;
+ eglQuerySurface_t eglQuerySurface;
+ eglBindAPI_t eglBindAPI;
+ eglQueryAPI_t eglQueryAPI;
+ eglWaitClient_t eglWaitClient;
+ eglReleaseThread_t eglReleaseThread;
+ eglCreatePbufferFromClientBuffer_t eglCreatePbufferFromClientBuffer;
+ eglSurfaceAttrib_t eglSurfaceAttrib;
+ eglBindTexImage_t eglBindTexImage;
+ eglReleaseTexImage_t eglReleaseTexImage;
+ eglSwapInterval_t eglSwapInterval;
+ eglCreateContext_t eglCreateContext;
+ eglDestroyContext_t eglDestroyContext;
+ eglMakeCurrent_t eglMakeCurrent;
+ eglGetCurrentContext_t eglGetCurrentContext;
+ eglGetCurrentSurface_t eglGetCurrentSurface;
+ eglGetCurrentDisplay_t eglGetCurrentDisplay;
+ eglQueryContext_t eglQueryContext;
+ eglWaitGL_t eglWaitGL;
+ eglWaitNative_t eglWaitNative;
+ eglSwapBuffers_t eglSwapBuffers;
+ eglCopyBuffers_t eglCopyBuffers;
+ eglGetProcAddress_t eglGetProcAddress;
+ eglLockSurfaceKHR_t eglLockSurfaceKHR;
+ eglUnlockSurfaceKHR_t eglUnlockSurfaceKHR;
+ eglCreateImageKHR_t eglCreateImageKHR;
+ eglDestroyImageKHR_t eglDestroyImageKHR;
+ eglCreateSyncKHR_t eglCreateSyncKHR;
+ eglDestroySyncKHR_t eglDestroySyncKHR;
+ eglClientWaitSyncKHR_t eglClientWaitSyncKHR;
+ eglSignalSyncKHR_t eglSignalSyncKHR;
+ eglGetSyncAttribKHR_t eglGetSyncAttribKHR;
+ eglSetSwapRectangleANDROID_t eglSetSwapRectangleANDROID;
+ //Accessors
+ eglGetError_t set_eglGetError(eglGetError_t f) { eglGetError_t retval = eglGetError; eglGetError = f; return retval;}
+ eglGetDisplay_t set_eglGetDisplay(eglGetDisplay_t f) { eglGetDisplay_t retval = eglGetDisplay; eglGetDisplay = f; return retval;}
+ eglInitialize_t set_eglInitialize(eglInitialize_t f) { eglInitialize_t retval = eglInitialize; eglInitialize = f; return retval;}
+ eglTerminate_t set_eglTerminate(eglTerminate_t f) { eglTerminate_t retval = eglTerminate; eglTerminate = f; return retval;}
+ eglQueryString_t set_eglQueryString(eglQueryString_t f) { eglQueryString_t retval = eglQueryString; eglQueryString = f; return retval;}
+ eglGetConfigs_t set_eglGetConfigs(eglGetConfigs_t f) { eglGetConfigs_t retval = eglGetConfigs; eglGetConfigs = f; return retval;}
+ eglChooseConfig_t set_eglChooseConfig(eglChooseConfig_t f) { eglChooseConfig_t retval = eglChooseConfig; eglChooseConfig = f; return retval;}
+ eglGetConfigAttrib_t set_eglGetConfigAttrib(eglGetConfigAttrib_t f) { eglGetConfigAttrib_t retval = eglGetConfigAttrib; eglGetConfigAttrib = f; return retval;}
+ eglCreateWindowSurface_t set_eglCreateWindowSurface(eglCreateWindowSurface_t f) { eglCreateWindowSurface_t retval = eglCreateWindowSurface; eglCreateWindowSurface = f; return retval;}
+ eglCreatePbufferSurface_t set_eglCreatePbufferSurface(eglCreatePbufferSurface_t f) { eglCreatePbufferSurface_t retval = eglCreatePbufferSurface; eglCreatePbufferSurface = f; return retval;}
+ eglCreatePixmapSurface_t set_eglCreatePixmapSurface(eglCreatePixmapSurface_t f) { eglCreatePixmapSurface_t retval = eglCreatePixmapSurface; eglCreatePixmapSurface = f; return retval;}
+ eglDestroySurface_t set_eglDestroySurface(eglDestroySurface_t f) { eglDestroySurface_t retval = eglDestroySurface; eglDestroySurface = f; return retval;}
+ eglQuerySurface_t set_eglQuerySurface(eglQuerySurface_t f) { eglQuerySurface_t retval = eglQuerySurface; eglQuerySurface = f; return retval;}
+ eglBindAPI_t set_eglBindAPI(eglBindAPI_t f) { eglBindAPI_t retval = eglBindAPI; eglBindAPI = f; return retval;}
+ eglQueryAPI_t set_eglQueryAPI(eglQueryAPI_t f) { eglQueryAPI_t retval = eglQueryAPI; eglQueryAPI = f; return retval;}
+ eglWaitClient_t set_eglWaitClient(eglWaitClient_t f) { eglWaitClient_t retval = eglWaitClient; eglWaitClient = f; return retval;}
+ eglReleaseThread_t set_eglReleaseThread(eglReleaseThread_t f) { eglReleaseThread_t retval = eglReleaseThread; eglReleaseThread = f; return retval;}
+ eglCreatePbufferFromClientBuffer_t set_eglCreatePbufferFromClientBuffer(eglCreatePbufferFromClientBuffer_t f) { eglCreatePbufferFromClientBuffer_t retval = eglCreatePbufferFromClientBuffer; eglCreatePbufferFromClientBuffer = f; return retval;}
+ eglSurfaceAttrib_t set_eglSurfaceAttrib(eglSurfaceAttrib_t f) { eglSurfaceAttrib_t retval = eglSurfaceAttrib; eglSurfaceAttrib = f; return retval;}
+ eglBindTexImage_t set_eglBindTexImage(eglBindTexImage_t f) { eglBindTexImage_t retval = eglBindTexImage; eglBindTexImage = f; return retval;}
+ eglReleaseTexImage_t set_eglReleaseTexImage(eglReleaseTexImage_t f) { eglReleaseTexImage_t retval = eglReleaseTexImage; eglReleaseTexImage = f; return retval;}
+ eglSwapInterval_t set_eglSwapInterval(eglSwapInterval_t f) { eglSwapInterval_t retval = eglSwapInterval; eglSwapInterval = f; return retval;}
+ eglCreateContext_t set_eglCreateContext(eglCreateContext_t f) { eglCreateContext_t retval = eglCreateContext; eglCreateContext = f; return retval;}
+ eglDestroyContext_t set_eglDestroyContext(eglDestroyContext_t f) { eglDestroyContext_t retval = eglDestroyContext; eglDestroyContext = f; return retval;}
+ eglMakeCurrent_t set_eglMakeCurrent(eglMakeCurrent_t f) { eglMakeCurrent_t retval = eglMakeCurrent; eglMakeCurrent = f; return retval;}
+ eglGetCurrentContext_t set_eglGetCurrentContext(eglGetCurrentContext_t f) { eglGetCurrentContext_t retval = eglGetCurrentContext; eglGetCurrentContext = f; return retval;}
+ eglGetCurrentSurface_t set_eglGetCurrentSurface(eglGetCurrentSurface_t f) { eglGetCurrentSurface_t retval = eglGetCurrentSurface; eglGetCurrentSurface = f; return retval;}
+ eglGetCurrentDisplay_t set_eglGetCurrentDisplay(eglGetCurrentDisplay_t f) { eglGetCurrentDisplay_t retval = eglGetCurrentDisplay; eglGetCurrentDisplay = f; return retval;}
+ eglQueryContext_t set_eglQueryContext(eglQueryContext_t f) { eglQueryContext_t retval = eglQueryContext; eglQueryContext = f; return retval;}
+ eglWaitGL_t set_eglWaitGL(eglWaitGL_t f) { eglWaitGL_t retval = eglWaitGL; eglWaitGL = f; return retval;}
+ eglWaitNative_t set_eglWaitNative(eglWaitNative_t f) { eglWaitNative_t retval = eglWaitNative; eglWaitNative = f; return retval;}
+ eglSwapBuffers_t set_eglSwapBuffers(eglSwapBuffers_t f) { eglSwapBuffers_t retval = eglSwapBuffers; eglSwapBuffers = f; return retval;}
+ eglCopyBuffers_t set_eglCopyBuffers(eglCopyBuffers_t f) { eglCopyBuffers_t retval = eglCopyBuffers; eglCopyBuffers = f; return retval;}
+ eglGetProcAddress_t set_eglGetProcAddress(eglGetProcAddress_t f) { eglGetProcAddress_t retval = eglGetProcAddress; eglGetProcAddress = f; return retval;}
+ eglLockSurfaceKHR_t set_eglLockSurfaceKHR(eglLockSurfaceKHR_t f) { eglLockSurfaceKHR_t retval = eglLockSurfaceKHR; eglLockSurfaceKHR = f; return retval;}
+ eglUnlockSurfaceKHR_t set_eglUnlockSurfaceKHR(eglUnlockSurfaceKHR_t f) { eglUnlockSurfaceKHR_t retval = eglUnlockSurfaceKHR; eglUnlockSurfaceKHR = f; return retval;}
+ eglCreateImageKHR_t set_eglCreateImageKHR(eglCreateImageKHR_t f) { eglCreateImageKHR_t retval = eglCreateImageKHR; eglCreateImageKHR = f; return retval;}
+ eglDestroyImageKHR_t set_eglDestroyImageKHR(eglDestroyImageKHR_t f) { eglDestroyImageKHR_t retval = eglDestroyImageKHR; eglDestroyImageKHR = f; return retval;}
+ eglCreateSyncKHR_t set_eglCreateSyncKHR(eglCreateSyncKHR_t f) { eglCreateSyncKHR_t retval = eglCreateSyncKHR; eglCreateSyncKHR = f; return retval;}
+ eglDestroySyncKHR_t set_eglDestroySyncKHR(eglDestroySyncKHR_t f) { eglDestroySyncKHR_t retval = eglDestroySyncKHR; eglDestroySyncKHR = f; return retval;}
+ eglClientWaitSyncKHR_t set_eglClientWaitSyncKHR(eglClientWaitSyncKHR_t f) { eglClientWaitSyncKHR_t retval = eglClientWaitSyncKHR; eglClientWaitSyncKHR = f; return retval;}
+ eglSignalSyncKHR_t set_eglSignalSyncKHR(eglSignalSyncKHR_t f) { eglSignalSyncKHR_t retval = eglSignalSyncKHR; eglSignalSyncKHR = f; return retval;}
+ eglGetSyncAttribKHR_t set_eglGetSyncAttribKHR(eglGetSyncAttribKHR_t f) { eglGetSyncAttribKHR_t retval = eglGetSyncAttribKHR; eglGetSyncAttribKHR = f; return retval;}
+ eglSetSwapRectangleANDROID_t set_eglSetSwapRectangleANDROID(eglSetSwapRectangleANDROID_t f) { eglSetSwapRectangleANDROID_t retval = eglSetSwapRectangleANDROID; eglSetSwapRectangleANDROID = f; return retval;}
+};
+
+egl_dispatch *create_egl_dispatch(void *gles_andorid);
+
+#endif
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl_ftable.h b/tools/emulator/opengl/tests/gles_android_wrapper/egl_ftable.h
new file mode 100644
index 0000000..ee40585
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl_ftable.h
@@ -0,0 +1,66 @@
+/*
+* 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.
+*/
+static struct _egl_funcs_by_name {
+ const char *name;
+ void *proc;
+} egl_funcs_by_name[] = {
+ {"eglGetError", (void *)eglGetError},
+ {"eglGetDisplay", (void *)eglGetDisplay},
+ {"eglInitialize", (void *)eglInitialize},
+ {"eglTerminate", (void *)eglTerminate},
+ {"eglQueryString", (void *)eglQueryString},
+ {"eglGetConfigs", (void *)eglGetConfigs},
+ {"eglChooseConfig", (void *)eglChooseConfig},
+ {"eglGetConfigAttrib", (void *)eglGetConfigAttrib},
+ {"eglCreateWindowSurface", (void *)eglCreateWindowSurface},
+ {"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface},
+ {"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface},
+ {"eglDestroySurface", (void *)eglDestroySurface},
+ {"eglQuerySurface", (void *)eglQuerySurface},
+ {"eglBindAPI", (void *)eglBindAPI},
+ {"eglQueryAPI", (void *)eglQueryAPI},
+ {"eglWaitClient", (void *)eglWaitClient},
+ {"eglReleaseThread", (void *)eglReleaseThread},
+ {"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer},
+ {"eglSurfaceAttrib", (void *)eglSurfaceAttrib},
+ {"eglBindTexImage", (void *)eglBindTexImage},
+ {"eglReleaseTexImage", (void *)eglReleaseTexImage},
+ {"eglSwapInterval", (void *)eglSwapInterval},
+ {"eglCreateContext", (void *)eglCreateContext},
+ {"eglDestroyContext", (void *)eglDestroyContext},
+ {"eglMakeCurrent", (void *)eglMakeCurrent},
+ {"eglGetCurrentContext", (void *)eglGetCurrentContext},
+ {"eglGetCurrentSurface", (void *)eglGetCurrentSurface},
+ {"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay},
+ {"eglQueryContext", (void *)eglQueryContext},
+ {"eglWaitGL", (void *)eglWaitGL},
+ {"eglWaitNative", (void *)eglWaitNative},
+ {"eglSwapBuffers", (void *)eglSwapBuffers},
+ {"eglCopyBuffers", (void *)eglCopyBuffers},
+ {"eglGetProcAddress", (void *)eglGetProcAddress},
+ {"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR},
+ {"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR},
+ {"eglCreateImageKHR", (void *)eglCreateImageKHR},
+ {"eglDestroyImageKHR", (void *)eglDestroyImageKHR},
+ {"eglCreateSyncKHR", (void *)eglCreateSyncKHR},
+ {"eglDestroySyncKHR", (void *)eglDestroySyncKHR},
+ {"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR},
+ {"eglSignalSyncKHR", (void *)eglSignalSyncKHR},
+ {"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR},
+ {"eglSetSwapRectangleANDROID", (void *)eglSetSwapRectangleANDROID}
+};
+
+static int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/egl_proc.h b/tools/emulator/opengl/tests/gles_android_wrapper/egl_proc.h
new file mode 100644
index 0000000..140c030
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/egl_proc.h
@@ -0,0 +1,68 @@
+/*
+* 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.
+*/
+#ifndef _EGL_PROC_H
+#define _EGL_PROC_H
+
+#include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+
+typedef EGLint (* eglGetError_t) ();
+typedef EGLDisplay (* eglGetDisplay_t) (EGLNativeDisplayType);
+typedef EGLBoolean (* eglInitialize_t) (EGLDisplay, EGLint*, EGLint*);
+typedef EGLBoolean (* eglTerminate_t) (EGLDisplay);
+typedef char* (* eglQueryString_t) (EGLDisplay, EGLint);
+typedef EGLBoolean (* eglGetConfigs_t) (EGLDisplay, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglChooseConfig_t) (EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*);
+typedef EGLBoolean (* eglGetConfigAttrib_t) (EGLDisplay, EGLConfig, EGLint, EGLint*);
+typedef EGLSurface (* eglCreateWindowSurface_t) (EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint*);
+typedef EGLSurface (* eglCreatePbufferSurface_t) (EGLDisplay, EGLConfig, const EGLint*);
+typedef EGLSurface (* eglCreatePixmapSurface_t) (EGLDisplay, EGLConfig, EGLNativePixmapType, const EGLint*);
+typedef EGLBoolean (* eglDestroySurface_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglQuerySurface_t) (EGLDisplay, EGLSurface, EGLint, EGLint*);
+typedef EGLBoolean (* eglBindAPI_t) (EGLenum);
+typedef EGLenum (* eglQueryAPI_t) ();
+typedef EGLBoolean (* eglWaitClient_t) ();
+typedef EGLBoolean (* eglReleaseThread_t) ();
+typedef EGLSurface (* eglCreatePbufferFromClientBuffer_t) (EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint*);
+typedef EGLBoolean (* eglSurfaceAttrib_t) (EGLDisplay, EGLSurface, EGLint, EGLint);
+typedef EGLBoolean (* eglBindTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglReleaseTexImage_t) (EGLDisplay, EGLSurface, EGLint);
+typedef EGLBoolean (* eglSwapInterval_t) (EGLDisplay, EGLint);
+typedef EGLContext (* eglCreateContext_t) (EGLDisplay, EGLConfig, EGLContext, const EGLint*);
+typedef EGLBoolean (* eglDestroyContext_t) (EGLDisplay, EGLContext);
+typedef EGLBoolean (* eglMakeCurrent_t) (EGLDisplay, EGLSurface, EGLSurface, EGLContext);
+typedef EGLContext (* eglGetCurrentContext_t) ();
+typedef EGLSurface (* eglGetCurrentSurface_t) (EGLint);
+typedef EGLDisplay (* eglGetCurrentDisplay_t) ();
+typedef EGLBoolean (* eglQueryContext_t) (EGLDisplay, EGLContext, EGLint, EGLint*);
+typedef EGLBoolean (* eglWaitGL_t) ();
+typedef EGLBoolean (* eglWaitNative_t) (EGLint);
+typedef EGLBoolean (* eglSwapBuffers_t) (EGLDisplay, EGLSurface);
+typedef EGLBoolean (* eglCopyBuffers_t) (EGLDisplay, EGLSurface, EGLNativePixmapType);
+typedef __eglMustCastToProperFunctionPointerType (* eglGetProcAddress_t) (const char*);
+typedef EGLBoolean (* eglLockSurfaceKHR_t) (EGLDisplay, EGLSurface, const EGLint*);
+typedef EGLBoolean (* eglUnlockSurfaceKHR_t) (EGLDisplay, EGLSurface);
+typedef EGLImageKHR (* eglCreateImageKHR_t) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
+typedef EGLBoolean (* eglDestroyImageKHR_t) (EGLDisplay, EGLImageKHR image);
+typedef EGLSyncKHR (* eglCreateSyncKHR_t) (EGLDisplay, EGLenum, const EGLint*);
+typedef EGLBoolean (* eglDestroySyncKHR_t) (EGLDisplay, EGLSyncKHR sync);
+typedef EGLint (* eglClientWaitSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR timeout);
+typedef EGLBoolean (* eglSignalSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLenum);
+typedef EGLBoolean (* eglGetSyncAttribKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLint*);
+typedef EGLBoolean (* eglSetSwapRectangleANDROID_t) (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
+
+#endif // of _EGL_PROC_H
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/gles.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/gles.cpp
new file mode 100644
index 0000000..f0a22aa
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/gles.cpp
@@ -0,0 +1,1410 @@
+/*
+* 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gles_dispatch.h"
+#include "gles_ftable.h"
+#include <EGL/egl.h>
+#include <cutils/log.h>
+
+static struct gles_dispatch *s_dispatch = NULL;
+
+void init_gles(void *gles_android)
+{
+ s_dispatch = create_gles_dispatch(gles_android);
+ if (s_dispatch == NULL) {
+ LOGE("failed to create gles dispatch\n");
+ }
+}
+
+static struct gles_dispatch *getDispatch()
+{
+ if (!s_dispatch) {
+ fprintf(stderr,"FATAL ERROR: GLES has not been initialized\n");
+ exit(-1);
+ }
+
+ return s_dispatch;
+}
+
+__eglMustCastToProperFunctionPointerType gles_getProcAddress(const char *procname)
+{
+ for (int i=0; i<gles_num_funcs; i++) {
+ if (!strcmp(gles_funcs_by_name[i].name, procname)) {
+ return (__eglMustCastToProperFunctionPointerType)gles_funcs_by_name[i].proc;
+ }
+ }
+
+ return NULL;
+}
+
+///////////// Path-through functions ///////////////
+void glAlphaFunc(GLenum func, GLclampf ref)
+{
+ getDispatch()->glAlphaFunc(func, ref);
+}
+
+void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ getDispatch()->glClearColor(red, green, blue, alpha);
+}
+
+void glClearDepthf(GLclampf depth)
+{
+ getDispatch()->glClearDepthf(depth);
+}
+
+void glClipPlanef(GLenum plane, const GLfloat *equation)
+{
+ getDispatch()->glClipPlanef(plane, equation);
+}
+
+void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ getDispatch()->glColor4f(red, green, blue, alpha);
+}
+
+void glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+ getDispatch()->glDepthRangef(zNear, zFar);
+}
+
+void glFogf(GLenum pname, GLfloat param)
+{
+ getDispatch()->glFogf(pname, param);
+}
+
+void glFogfv(GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glFogfv(pname, params);
+}
+
+void glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+ getDispatch()->glFrustumf(left, right, bottom, top, zNear, zFar);
+}
+
+void glGetClipPlanef(GLenum pname, GLfloat eqn[4])
+{
+ getDispatch()->glGetClipPlanef(pname, eqn);
+}
+
+void glGetFloatv(GLenum pname, GLfloat *params)
+{
+ getDispatch()->glGetFloatv(pname, params);
+}
+
+void glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+ getDispatch()->glGetLightfv(light, pname, params);
+}
+
+void glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+ getDispatch()->glGetMaterialfv(face, pname, params);
+}
+
+void glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
+{
+ getDispatch()->glGetTexEnvfv(env, pname, params);
+}
+
+void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ getDispatch()->glGetTexParameterfv(target, pname, params);
+}
+
+void glLightModelf(GLenum pname, GLfloat param)
+{
+ getDispatch()->glLightModelf(pname, param);
+}
+
+void glLightModelfv(GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glLightModelfv(pname, params);
+}
+
+void glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+ getDispatch()->glLightf(light, pname, param);
+}
+
+void glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glLightfv(light, pname, params);
+}
+
+void glLineWidth(GLfloat width)
+{
+ getDispatch()->glLineWidth(width);
+}
+
+void glLoadMatrixf(const GLfloat *m)
+{
+ getDispatch()->glLoadMatrixf(m);
+}
+
+void glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+ getDispatch()->glMaterialf(face, pname, param);
+}
+
+void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glMaterialfv(face, pname, params);
+}
+
+void glMultMatrixf(const GLfloat *m)
+{
+ getDispatch()->glMultMatrixf(m);
+}
+
+void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ getDispatch()->glMultiTexCoord4f(target, s, t, r, q);
+}
+
+void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+ getDispatch()->glNormal3f(nx, ny, nz);
+}
+
+void glOrthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+ getDispatch()->glOrthof(left, right, bottom, top, zNear, zFar);
+}
+
+void glPointParameterf(GLenum pname, GLfloat param)
+{
+ getDispatch()->glPointParameterf(pname, param);
+}
+
+void glPointParameterfv(GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glPointParameterfv(pname, params);
+}
+
+void glPointSize(GLfloat size)
+{
+ getDispatch()->glPointSize(size);
+}
+
+void glPolygonOffset(GLfloat factor, GLfloat units)
+{
+ getDispatch()->glPolygonOffset(factor, units);
+}
+
+void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ getDispatch()->glRotatef(angle, x, y, z);
+}
+
+void glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ getDispatch()->glScalef(x, y, z);
+}
+
+void glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ getDispatch()->glTexEnvf(target, pname, param);
+}
+
+void glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glTexEnvfv(target, pname, params);
+}
+
+void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ getDispatch()->glTexParameterf(target, pname, param);
+}
+
+void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glTexParameterfv(target, pname, params);
+}
+
+void glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ getDispatch()->glTranslatef(x, y, z);
+}
+
+void glActiveTexture(GLenum texture)
+{
+ getDispatch()->glActiveTexture(texture);
+}
+
+void glAlphaFuncx(GLenum func, GLclampx ref)
+{
+ getDispatch()->glAlphaFuncx(func, ref);
+}
+
+void glBindBuffer(GLenum target, GLuint buffer)
+{
+ getDispatch()->glBindBuffer(target, buffer);
+}
+
+void glBindTexture(GLenum target, GLuint texture)
+{
+ getDispatch()->glBindTexture(target, texture);
+}
+
+void glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ getDispatch()->glBlendFunc(sfactor, dfactor);
+}
+
+void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
+{
+ getDispatch()->glBufferData(target, size, data, usage);
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
+{
+ getDispatch()->glBufferSubData(target, offset, size, data);
+}
+
+void glClear(GLbitfield mask)
+{
+ getDispatch()->glClear(mask);
+}
+
+void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+ getDispatch()->glClearColorx(red, green, blue, alpha);
+}
+
+void glClearDepthx(GLclampx depth)
+{
+ getDispatch()->glClearDepthx(depth);
+}
+
+void glClearStencil(GLint s)
+{
+ getDispatch()->glClearStencil(s);
+}
+
+void glClientActiveTexture(GLenum texture)
+{
+ getDispatch()->glClientActiveTexture(texture);
+}
+
+void glClipPlanex(GLenum plane, const GLfixed *equation)
+{
+ getDispatch()->glClipPlanex(plane, equation);
+}
+
+void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+ getDispatch()->glColor4ub(red, green, blue, alpha);
+}
+
+void glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ getDispatch()->glColor4x(red, green, blue, alpha);
+}
+
+void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ getDispatch()->glColorMask(red, green, blue, alpha);
+}
+
+void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ getDispatch()->glColorPointer(size, type, stride, pointer);
+}
+
+void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
+{
+ getDispatch()->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
+{
+ getDispatch()->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ getDispatch()->glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ getDispatch()->glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+void glCullFace(GLenum mode)
+{
+ getDispatch()->glCullFace(mode);
+}
+
+void glDeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+ getDispatch()->glDeleteBuffers(n, buffers);
+}
+
+void glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+ getDispatch()->glDeleteTextures(n, textures);
+}
+
+void glDepthFunc(GLenum func)
+{
+ getDispatch()->glDepthFunc(func);
+}
+
+void glDepthMask(GLboolean flag)
+{
+ getDispatch()->glDepthMask(flag);
+}
+
+void glDepthRangex(GLclampx zNear, GLclampx zFar)
+{
+ getDispatch()->glDepthRangex(zNear, zFar);
+}
+
+void glDisable(GLenum cap)
+{
+ getDispatch()->glDisable(cap);
+}
+
+void glDisableClientState(GLenum array)
+{
+ getDispatch()->glDisableClientState(array);
+}
+
+void glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ getDispatch()->glDrawArrays(mode, first, count);
+}
+
+void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+ getDispatch()->glDrawElements(mode, count, type, indices);
+}
+
+void glEnable(GLenum cap)
+{
+ getDispatch()->glEnable(cap);
+}
+
+void glEnableClientState(GLenum array)
+{
+ getDispatch()->glEnableClientState(array);
+}
+
+void glFinish()
+{
+ getDispatch()->glFinish();
+}
+
+void glFlush()
+{
+ getDispatch()->glFlush();
+}
+
+void glFogx(GLenum pname, GLfixed param)
+{
+ getDispatch()->glFogx(pname, param);
+}
+
+void glFogxv(GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glFogxv(pname, params);
+}
+
+void glFrontFace(GLenum mode)
+{
+ getDispatch()->glFrontFace(mode);
+}
+
+void glFrustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+ getDispatch()->glFrustumx(left, right, bottom, top, zNear, zFar);
+}
+
+void glGetBooleanv(GLenum pname, GLboolean *params)
+{
+ getDispatch()->glGetBooleanv(pname, params);
+}
+
+void glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ getDispatch()->glGetBufferParameteriv(target, pname, params);
+}
+
+void glGetClipPlanex(GLenum pname, GLfixed eqn[4])
+{
+ getDispatch()->glGetClipPlanex(pname, eqn);
+}
+
+void glGenBuffers(GLsizei n, GLuint *buffers)
+{
+ getDispatch()->glGenBuffers(n, buffers);
+}
+
+void glGenTextures(GLsizei n, GLuint *textures)
+{
+ getDispatch()->glGenTextures(n, textures);
+}
+
+GLenum glGetError()
+{
+ return getDispatch()->glGetError();
+}
+
+void glGetFixedv(GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetFixedv(pname, params);
+}
+
+void glGetIntegerv(GLenum pname, GLint *params)
+{
+ getDispatch()->glGetIntegerv(pname, params);
+}
+
+void glGetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetLightxv(light, pname, params);
+}
+
+void glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetMaterialxv(face, pname, params);
+}
+
+void glGetPointerv(GLenum pname, GLvoid **params)
+{
+ getDispatch()->glGetPointerv(pname, params);
+}
+
+const GLubyte* glGetString(GLenum name)
+{
+ return getDispatch()->glGetString(name);
+}
+
+void glGetTexEnviv(GLenum env, GLenum pname, GLint *params)
+{
+ getDispatch()->glGetTexEnviv(env, pname, params);
+}
+
+void glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetTexEnvxv(env, pname, params);
+}
+
+void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ getDispatch()->glGetTexParameteriv(target, pname, params);
+}
+
+void glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetTexParameterxv(target, pname, params);
+}
+
+void glHint(GLenum target, GLenum mode)
+{
+ getDispatch()->glHint(target, mode);
+}
+
+GLboolean glIsBuffer(GLuint buffer)
+{
+ return getDispatch()->glIsBuffer(buffer);
+}
+
+GLboolean glIsEnabled(GLenum cap)
+{
+ return getDispatch()->glIsEnabled(cap);
+}
+
+GLboolean glIsTexture(GLuint texture)
+{
+ return getDispatch()->glIsTexture(texture);
+}
+
+void glLightModelx(GLenum pname, GLfixed param)
+{
+ getDispatch()->glLightModelx(pname, param);
+}
+
+void glLightModelxv(GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glLightModelxv(pname, params);
+}
+
+void glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+ getDispatch()->glLightx(light, pname, param);
+}
+
+void glLightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glLightxv(light, pname, params);
+}
+
+void glLineWidthx(GLfixed width)
+{
+ getDispatch()->glLineWidthx(width);
+}
+
+void glLoadIdentity()
+{
+ getDispatch()->glLoadIdentity();
+}
+
+void glLoadMatrixx(const GLfixed *m)
+{
+ getDispatch()->glLoadMatrixx(m);
+}
+
+void glLogicOp(GLenum opcode)
+{
+ getDispatch()->glLogicOp(opcode);
+}
+
+void glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+ getDispatch()->glMaterialx(face, pname, param);
+}
+
+void glMaterialxv(GLenum face, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glMaterialxv(face, pname, params);
+}
+
+void glMatrixMode(GLenum mode)
+{
+ getDispatch()->glMatrixMode(mode);
+}
+
+void glMultMatrixx(const GLfixed *m)
+{
+ getDispatch()->glMultMatrixx(m);
+}
+
+void glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+ getDispatch()->glMultiTexCoord4x(target, s, t, r, q);
+}
+
+void glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+ getDispatch()->glNormal3x(nx, ny, nz);
+}
+
+void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ getDispatch()->glNormalPointer(type, stride, pointer);
+}
+
+void glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+ getDispatch()->glOrthox(left, right, bottom, top, zNear, zFar);
+}
+
+void glPixelStorei(GLenum pname, GLint param)
+{
+ getDispatch()->glPixelStorei(pname, param);
+}
+
+void glPointParameterx(GLenum pname, GLfixed param)
+{
+ getDispatch()->glPointParameterx(pname, param);
+}
+
+void glPointParameterxv(GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glPointParameterxv(pname, params);
+}
+
+void glPointSizex(GLfixed size)
+{
+ getDispatch()->glPointSizex(size);
+}
+
+void glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+ getDispatch()->glPolygonOffsetx(factor, units);
+}
+
+void glPopMatrix()
+{
+ getDispatch()->glPopMatrix();
+}
+
+void glPushMatrix()
+{
+ getDispatch()->glPushMatrix();
+}
+
+void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+{
+ getDispatch()->glReadPixels(x, y, width, height, format, type, pixels);
+}
+
+void glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+ getDispatch()->glRotatex(angle, x, y, z);
+}
+
+void glSampleCoverage(GLclampf value, GLboolean invert)
+{
+ getDispatch()->glSampleCoverage(value, invert);
+}
+
+void glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+ getDispatch()->glSampleCoveragex(value, invert);
+}
+
+void glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+ getDispatch()->glScalex(x, y, z);
+}
+
+void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ getDispatch()->glScissor(x, y, width, height);
+}
+
+void glShadeModel(GLenum mode)
+{
+ getDispatch()->glShadeModel(mode);
+}
+
+void glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ getDispatch()->glStencilFunc(func, ref, mask);
+}
+
+void glStencilMask(GLuint mask)
+{
+ getDispatch()->glStencilMask(mask);
+}
+
+void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ getDispatch()->glStencilOp(fail, zfail, zpass);
+}
+
+void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ getDispatch()->glTexCoordPointer(size, type, stride, pointer);
+}
+
+void glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ getDispatch()->glTexEnvi(target, pname, param);
+}
+
+void glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+ getDispatch()->glTexEnvx(target, pname, param);
+}
+
+void glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+ getDispatch()->glTexEnviv(target, pname, params);
+}
+
+void glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glTexEnvxv(target, pname, params);
+}
+
+void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ getDispatch()->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+void glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ getDispatch()->glTexParameteri(target, pname, param);
+}
+
+void glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+ getDispatch()->glTexParameterx(target, pname, param);
+}
+
+void glTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ getDispatch()->glTexParameteriv(target, pname, params);
+}
+
+void glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glTexParameterxv(target, pname, params);
+}
+
+void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ getDispatch()->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+ getDispatch()->glTranslatex(x, y, z);
+}
+
+void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ getDispatch()->glVertexPointer(size, type, stride, pointer);
+}
+
+void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ getDispatch()->glViewport(x, y, width, height);
+}
+
+void glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ getDispatch()->glPointSizePointerOES(type, stride, pointer);
+}
+
+void glBlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
+{
+ getDispatch()->glBlendEquationSeparateOES(modeRGB, modeAlpha);
+}
+
+void glBlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ getDispatch()->glBlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void glBlendEquationOES(GLenum mode)
+{
+ getDispatch()->glBlendEquationOES(mode);
+}
+
+void glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+ getDispatch()->glDrawTexsOES(x, y, z, width, height);
+}
+
+void glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+ getDispatch()->glDrawTexiOES(x, y, z, width, height);
+}
+
+void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+ getDispatch()->glDrawTexxOES(x, y, z, width, height);
+}
+
+void glDrawTexsvOES(const GLshort *coords)
+{
+ getDispatch()->glDrawTexsvOES(coords);
+}
+
+void glDrawTexivOES(const GLint *coords)
+{
+ getDispatch()->glDrawTexivOES(coords);
+}
+
+void glDrawTexxvOES(const GLfixed *coords)
+{
+ getDispatch()->glDrawTexxvOES(coords);
+}
+
+void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+ getDispatch()->glDrawTexfOES(x, y, z, width, height);
+}
+
+void glDrawTexfvOES(const GLfloat *coords)
+{
+ getDispatch()->glDrawTexfvOES(coords);
+}
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+ getDispatch()->glEGLImageTargetTexture2DOES(target, image);
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+ getDispatch()->glEGLImageTargetRenderbufferStorageOES(target, image);
+}
+
+void glAlphaFuncxOES(GLenum func, GLclampx ref)
+{
+ getDispatch()->glAlphaFuncxOES(func, ref);
+}
+
+void glClearColorxOES(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+{
+ getDispatch()->glClearColorxOES(red, green, blue, alpha);
+}
+
+void glClearDepthxOES(GLclampx depth)
+{
+ getDispatch()->glClearDepthxOES(depth);
+}
+
+void glClipPlanexOES(GLenum plane, const GLfixed *equation)
+{
+ getDispatch()->glClipPlanexOES(plane, equation);
+}
+
+void glColor4xOES(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ getDispatch()->glColor4xOES(red, green, blue, alpha);
+}
+
+void glDepthRangexOES(GLclampx zNear, GLclampx zFar)
+{
+ getDispatch()->glDepthRangexOES(zNear, zFar);
+}
+
+void glFogxOES(GLenum pname, GLfixed param)
+{
+ getDispatch()->glFogxOES(pname, param);
+}
+
+void glFogxvOES(GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glFogxvOES(pname, params);
+}
+
+void glFrustumxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+ getDispatch()->glFrustumxOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glGetClipPlanexOES(GLenum pname, GLfixed eqn[4])
+{
+ getDispatch()->glGetClipPlanexOES(pname, eqn);
+}
+
+void glGetFixedvOES(GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetFixedvOES(pname, params);
+}
+
+void glGetLightxvOES(GLenum light, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetLightxvOES(light, pname, params);
+}
+
+void glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetMaterialxvOES(face, pname, params);
+}
+
+void glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetTexEnvxvOES(env, pname, params);
+}
+
+void glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetTexParameterxvOES(target, pname, params);
+}
+
+void glLightModelxOES(GLenum pname, GLfixed param)
+{
+ getDispatch()->glLightModelxOES(pname, param);
+}
+
+void glLightModelxvOES(GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glLightModelxvOES(pname, params);
+}
+
+void glLightxOES(GLenum light, GLenum pname, GLfixed param)
+{
+ getDispatch()->glLightxOES(light, pname, param);
+}
+
+void glLightxvOES(GLenum light, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glLightxvOES(light, pname, params);
+}
+
+void glLineWidthxOES(GLfixed width)
+{
+ getDispatch()->glLineWidthxOES(width);
+}
+
+void glLoadMatrixxOES(const GLfixed *m)
+{
+ getDispatch()->glLoadMatrixxOES(m);
+}
+
+void glMaterialxOES(GLenum face, GLenum pname, GLfixed param)
+{
+ getDispatch()->glMaterialxOES(face, pname, param);
+}
+
+void glMaterialxvOES(GLenum face, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glMaterialxvOES(face, pname, params);
+}
+
+void glMultMatrixxOES(const GLfixed *m)
+{
+ getDispatch()->glMultMatrixxOES(m);
+}
+
+void glMultiTexCoord4xOES(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+ getDispatch()->glMultiTexCoord4xOES(target, s, t, r, q);
+}
+
+void glNormal3xOES(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+ getDispatch()->glNormal3xOES(nx, ny, nz);
+}
+
+void glOrthoxOES(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+{
+ getDispatch()->glOrthoxOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glPointParameterxOES(GLenum pname, GLfixed param)
+{
+ getDispatch()->glPointParameterxOES(pname, param);
+}
+
+void glPointParameterxvOES(GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glPointParameterxvOES(pname, params);
+}
+
+void glPointSizexOES(GLfixed size)
+{
+ getDispatch()->glPointSizexOES(size);
+}
+
+void glPolygonOffsetxOES(GLfixed factor, GLfixed units)
+{
+ getDispatch()->glPolygonOffsetxOES(factor, units);
+}
+
+void glRotatexOES(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+ getDispatch()->glRotatexOES(angle, x, y, z);
+}
+
+void glSampleCoveragexOES(GLclampx value, GLboolean invert)
+{
+ getDispatch()->glSampleCoveragexOES(value, invert);
+}
+
+void glScalexOES(GLfixed x, GLfixed y, GLfixed z)
+{
+ getDispatch()->glScalexOES(x, y, z);
+}
+
+void glTexEnvxOES(GLenum target, GLenum pname, GLfixed param)
+{
+ getDispatch()->glTexEnvxOES(target, pname, param);
+}
+
+void glTexEnvxvOES(GLenum target, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glTexEnvxvOES(target, pname, params);
+}
+
+void glTexParameterxOES(GLenum target, GLenum pname, GLfixed param)
+{
+ getDispatch()->glTexParameterxOES(target, pname, param);
+}
+
+void glTexParameterxvOES(GLenum target, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glTexParameterxvOES(target, pname, params);
+}
+
+void glTranslatexOES(GLfixed x, GLfixed y, GLfixed z)
+{
+ getDispatch()->glTranslatexOES(x, y, z);
+}
+
+GLboolean glIsRenderbufferOES(GLuint renderbuffer)
+{
+ return getDispatch()->glIsRenderbufferOES(renderbuffer);
+}
+
+void glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+ getDispatch()->glBindRenderbufferOES(target, renderbuffer);
+}
+
+void glDeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers)
+{
+ getDispatch()->glDeleteRenderbuffersOES(n, renderbuffers);
+}
+
+void glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
+{
+ getDispatch()->glGenRenderbuffersOES(n, renderbuffers);
+}
+
+void glRenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ getDispatch()->glRenderbufferStorageOES(target, internalformat, width, height);
+}
+
+void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
+{
+ getDispatch()->glGetRenderbufferParameterivOES(target, pname, params);
+}
+
+GLboolean glIsFramebufferOES(GLuint framebuffer)
+{
+ return getDispatch()->glIsFramebufferOES(framebuffer);
+}
+
+void glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+ getDispatch()->glBindFramebufferOES(target, framebuffer);
+}
+
+void glDeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers)
+{
+ getDispatch()->glDeleteFramebuffersOES(n, framebuffers);
+}
+
+void glGenFramebuffersOES(GLsizei n, GLuint *framebuffers)
+{
+ getDispatch()->glGenFramebuffersOES(n, framebuffers);
+}
+
+GLenum glCheckFramebufferStatusOES(GLenum target)
+{
+ return getDispatch()->glCheckFramebufferStatusOES(target);
+}
+
+void glFramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ getDispatch()->glFramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void glFramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ getDispatch()->glFramebufferTexture2DOES(target, attachment, textarget, texture, level);
+}
+
+void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint *params)
+{
+ getDispatch()->glGetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
+}
+
+void glGenerateMipmapOES(GLenum target)
+{
+ getDispatch()->glGenerateMipmapOES(target);
+}
+
+void* glMapBufferOES(GLenum target, GLenum access)
+{
+ return getDispatch()->glMapBufferOES(target, access);
+}
+
+GLboolean glUnmapBufferOES(GLenum target)
+{
+ return getDispatch()->glUnmapBufferOES(target);
+}
+
+void glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid **ptr)
+{
+ getDispatch()->glGetBufferPointervOES(target, pname, ptr);
+}
+
+void glCurrentPaletteMatrixOES(GLuint matrixpaletteindex)
+{
+ getDispatch()->glCurrentPaletteMatrixOES(matrixpaletteindex);
+}
+
+void glLoadPaletteFromModelViewMatrixOES()
+{
+ getDispatch()->glLoadPaletteFromModelViewMatrixOES();
+}
+
+void glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ getDispatch()->glMatrixIndexPointerOES(size, type, stride, pointer);
+}
+
+void glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ getDispatch()->glWeightPointerOES(size, type, stride, pointer);
+}
+
+GLbitfield glQueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16])
+{
+ return getDispatch()->glQueryMatrixxOES(mantissa, exponent);
+}
+
+void glDepthRangefOES(GLclampf zNear, GLclampf zFar)
+{
+ getDispatch()->glDepthRangefOES(zNear, zFar);
+}
+
+void glFrustumfOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+ getDispatch()->glFrustumfOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glOrthofOES(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+{
+ getDispatch()->glOrthofOES(left, right, bottom, top, zNear, zFar);
+}
+
+void glClipPlanefOES(GLenum plane, const GLfloat *equation)
+{
+ getDispatch()->glClipPlanefOES(plane, equation);
+}
+
+void glGetClipPlanefOES(GLenum pname, GLfloat eqn[4])
+{
+ getDispatch()->glGetClipPlanefOES(pname, eqn);
+}
+
+void glClearDepthfOES(GLclampf depth)
+{
+ getDispatch()->glClearDepthfOES(depth);
+}
+
+void glTexGenfOES(GLenum coord, GLenum pname, GLfloat param)
+{
+ getDispatch()->glTexGenfOES(coord, pname, param);
+}
+
+void glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ getDispatch()->glTexGenfvOES(coord, pname, params);
+}
+
+void glTexGeniOES(GLenum coord, GLenum pname, GLint param)
+{
+ getDispatch()->glTexGeniOES(coord, pname, param);
+}
+
+void glTexGenivOES(GLenum coord, GLenum pname, const GLint *params)
+{
+ getDispatch()->glTexGenivOES(coord, pname, params);
+}
+
+void glTexGenxOES(GLenum coord, GLenum pname, GLfixed param)
+{
+ getDispatch()->glTexGenxOES(coord, pname, param);
+}
+
+void glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params)
+{
+ getDispatch()->glTexGenxvOES(coord, pname, params);
+}
+
+void glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params)
+{
+ getDispatch()->glGetTexGenfvOES(coord, pname, params);
+}
+
+void glGetTexGenivOES(GLenum coord, GLenum pname, GLint *params)
+{
+ getDispatch()->glGetTexGenivOES(coord, pname, params);
+}
+
+void glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params)
+{
+ getDispatch()->glGetTexGenxvOES(coord, pname, params);
+}
+
+void glBindVertexArrayOES(GLuint array)
+{
+ getDispatch()->glBindVertexArrayOES(array);
+}
+
+void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
+{
+ getDispatch()->glDeleteVertexArraysOES(n, arrays);
+}
+
+void glGenVertexArraysOES(GLsizei n, GLuint *arrays)
+{
+ getDispatch()->glGenVertexArraysOES(n, arrays);
+}
+
+GLboolean glIsVertexArrayOES(GLuint array)
+{
+ return getDispatch()->glIsVertexArrayOES(array);
+}
+
+void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments)
+{
+ getDispatch()->glDiscardFramebufferEXT(target, numAttachments, attachments);
+}
+
+void glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount)
+{
+ getDispatch()->glMultiDrawArraysEXT(mode, first, count, primcount);
+}
+
+void glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount)
+{
+ getDispatch()->glMultiDrawElementsEXT(mode, count, type, indices, primcount);
+}
+
+void glClipPlanefIMG(GLenum p, const GLfloat *eqn)
+{
+ getDispatch()->glClipPlanefIMG(p, eqn);
+}
+
+void glClipPlanexIMG(GLenum p, const GLfixed *eqn)
+{
+ getDispatch()->glClipPlanexIMG(p, eqn);
+}
+
+void glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ getDispatch()->glRenderbufferStorageMultisampleIMG(target, samples, internalformat, width, height);
+}
+
+void glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
+{
+ getDispatch()->glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, texture, level, samples);
+}
+
+void glDeleteFencesNV(GLsizei n, const GLuint *fences)
+{
+ getDispatch()->glDeleteFencesNV(n, fences);
+}
+
+void glGenFencesNV(GLsizei n, GLuint *fences)
+{
+ getDispatch()->glGenFencesNV(n, fences);
+}
+
+GLboolean glIsFenceNV(GLuint fence)
+{
+ return getDispatch()->glIsFenceNV(fence);
+}
+
+GLboolean glTestFenceNV(GLuint fence)
+{
+ return getDispatch()->glTestFenceNV(fence);
+}
+
+void glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+ getDispatch()->glGetFenceivNV(fence, pname, params);
+}
+
+void glFinishFenceNV(GLuint fence)
+{
+ getDispatch()->glFinishFenceNV(fence);
+}
+
+void glSetFenceNV(GLuint fence, GLenum condition)
+{
+ getDispatch()->glSetFenceNV(fence, condition);
+}
+
+void glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverControls)
+{
+ getDispatch()->glGetDriverControlsQCOM(num, size, driverControls);
+}
+
+void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString)
+{
+ getDispatch()->glGetDriverControlStringQCOM(driverControl, bufSize, length, driverControlString);
+}
+
+void glEnableDriverControlQCOM(GLuint driverControl)
+{
+ getDispatch()->glEnableDriverControlQCOM(driverControl);
+}
+
+void glDisableDriverControlQCOM(GLuint driverControl)
+{
+ getDispatch()->glDisableDriverControlQCOM(driverControl);
+}
+
+void glExtGetTexturesQCOM(GLuint *textures, GLint maxTextures, GLint *numTextures)
+{
+ getDispatch()->glExtGetTexturesQCOM(textures, maxTextures, numTextures);
+}
+
+void glExtGetBuffersQCOM(GLuint *buffers, GLint maxBuffers, GLint *numBuffers)
+{
+ getDispatch()->glExtGetBuffersQCOM(buffers, maxBuffers, numBuffers);
+}
+
+void glExtGetRenderbuffersQCOM(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers)
+{
+ getDispatch()->glExtGetRenderbuffersQCOM(renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+
+void glExtGetFramebuffersQCOM(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers)
+{
+ getDispatch()->glExtGetFramebuffersQCOM(framebuffers, maxFramebuffers, numFramebuffers);
+}
+
+void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params)
+{
+ getDispatch()->glExtGetTexLevelParameterivQCOM(texture, face, level, pname, params);
+}
+
+void glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param)
+{
+ getDispatch()->glExtTexObjectStateOverrideiQCOM(target, pname, param);
+}
+
+void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels)
+{
+ getDispatch()->glExtGetTexSubImageQCOM(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+
+void glExtGetBufferPointervQCOM(GLenum target, GLvoid **params)
+{
+ getDispatch()->glExtGetBufferPointervQCOM(target, params);
+}
+
+void glExtGetShadersQCOM(GLuint *shaders, GLint maxShaders, GLint *numShaders)
+{
+ getDispatch()->glExtGetShadersQCOM(shaders, maxShaders, numShaders);
+}
+
+void glExtGetProgramsQCOM(GLuint *programs, GLint maxPrograms, GLint *numPrograms)
+{
+ getDispatch()->glExtGetProgramsQCOM(programs, maxPrograms, numPrograms);
+}
+
+GLboolean glExtIsProgramBinaryQCOM(GLuint program)
+{
+ return getDispatch()->glExtIsProgramBinaryQCOM(program);
+}
+
+void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar *source, GLint *length)
+{
+ getDispatch()->glExtGetProgramBinarySourceQCOM(program, shadertype, source, length);
+}
+
+void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
+{
+ getDispatch()->glStartTilingQCOM(x, y, width, height, preserveMask);
+}
+
+void glEndTilingQCOM(GLbitfield preserveMask)
+{
+ getDispatch()->glEndTilingQCOM(preserveMask);
+}
+
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/gles_dispatch.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/gles_dispatch.cpp
new file mode 100644
index 0000000..0a17624
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/gles_dispatch.cpp
@@ -0,0 +1,298 @@
+/*
+* 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.
+*/
+#include "gles_dispatch.h"
+#include <stdio.h>
+#include <dlfcn.h>
+
+gles_dispatch *create_gles_dispatch(void *gles_android)
+{
+ gles_dispatch *disp = new gles_dispatch;
+
+ void *ptr;
+ ptr = dlsym(gles_android,"glAlphaFunc"); disp->set_glAlphaFunc((glAlphaFunc_t)ptr);
+ ptr = dlsym(gles_android,"glClearColor"); disp->set_glClearColor((glClearColor_t)ptr);
+ ptr = dlsym(gles_android,"glClearDepthf"); disp->set_glClearDepthf((glClearDepthf_t)ptr);
+ ptr = dlsym(gles_android,"glClipPlanef"); disp->set_glClipPlanef((glClipPlanef_t)ptr);
+ ptr = dlsym(gles_android,"glColor4f"); disp->set_glColor4f((glColor4f_t)ptr);
+ ptr = dlsym(gles_android,"glDepthRangef"); disp->set_glDepthRangef((glDepthRangef_t)ptr);
+ ptr = dlsym(gles_android,"glFogf"); disp->set_glFogf((glFogf_t)ptr);
+ ptr = dlsym(gles_android,"glFogfv"); disp->set_glFogfv((glFogfv_t)ptr);
+ ptr = dlsym(gles_android,"glFrustumf"); disp->set_glFrustumf((glFrustumf_t)ptr);
+ ptr = dlsym(gles_android,"glGetClipPlanef"); disp->set_glGetClipPlanef((glGetClipPlanef_t)ptr);
+ ptr = dlsym(gles_android,"glGetFloatv"); disp->set_glGetFloatv((glGetFloatv_t)ptr);
+ ptr = dlsym(gles_android,"glGetLightfv"); disp->set_glGetLightfv((glGetLightfv_t)ptr);
+ ptr = dlsym(gles_android,"glGetMaterialfv"); disp->set_glGetMaterialfv((glGetMaterialfv_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexEnvfv"); disp->set_glGetTexEnvfv((glGetTexEnvfv_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexParameterfv"); disp->set_glGetTexParameterfv((glGetTexParameterfv_t)ptr);
+ ptr = dlsym(gles_android,"glLightModelf"); disp->set_glLightModelf((glLightModelf_t)ptr);
+ ptr = dlsym(gles_android,"glLightModelfv"); disp->set_glLightModelfv((glLightModelfv_t)ptr);
+ ptr = dlsym(gles_android,"glLightf"); disp->set_glLightf((glLightf_t)ptr);
+ ptr = dlsym(gles_android,"glLightfv"); disp->set_glLightfv((glLightfv_t)ptr);
+ ptr = dlsym(gles_android,"glLineWidth"); disp->set_glLineWidth((glLineWidth_t)ptr);
+ ptr = dlsym(gles_android,"glLoadMatrixf"); disp->set_glLoadMatrixf((glLoadMatrixf_t)ptr);
+ ptr = dlsym(gles_android,"glMaterialf"); disp->set_glMaterialf((glMaterialf_t)ptr);
+ ptr = dlsym(gles_android,"glMaterialfv"); disp->set_glMaterialfv((glMaterialfv_t)ptr);
+ ptr = dlsym(gles_android,"glMultMatrixf"); disp->set_glMultMatrixf((glMultMatrixf_t)ptr);
+ ptr = dlsym(gles_android,"glMultiTexCoord4f"); disp->set_glMultiTexCoord4f((glMultiTexCoord4f_t)ptr);
+ ptr = dlsym(gles_android,"glNormal3f"); disp->set_glNormal3f((glNormal3f_t)ptr);
+ ptr = dlsym(gles_android,"glOrthof"); disp->set_glOrthof((glOrthof_t)ptr);
+ ptr = dlsym(gles_android,"glPointParameterf"); disp->set_glPointParameterf((glPointParameterf_t)ptr);
+ ptr = dlsym(gles_android,"glPointParameterfv"); disp->set_glPointParameterfv((glPointParameterfv_t)ptr);
+ ptr = dlsym(gles_android,"glPointSize"); disp->set_glPointSize((glPointSize_t)ptr);
+ ptr = dlsym(gles_android,"glPolygonOffset"); disp->set_glPolygonOffset((glPolygonOffset_t)ptr);
+ ptr = dlsym(gles_android,"glRotatef"); disp->set_glRotatef((glRotatef_t)ptr);
+ ptr = dlsym(gles_android,"glScalef"); disp->set_glScalef((glScalef_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnvf"); disp->set_glTexEnvf((glTexEnvf_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnvfv"); disp->set_glTexEnvfv((glTexEnvfv_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameterf"); disp->set_glTexParameterf((glTexParameterf_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameterfv"); disp->set_glTexParameterfv((glTexParameterfv_t)ptr);
+ ptr = dlsym(gles_android,"glTranslatef"); disp->set_glTranslatef((glTranslatef_t)ptr);
+ ptr = dlsym(gles_android,"glActiveTexture"); disp->set_glActiveTexture((glActiveTexture_t)ptr);
+ ptr = dlsym(gles_android,"glAlphaFuncx"); disp->set_glAlphaFuncx((glAlphaFuncx_t)ptr);
+ ptr = dlsym(gles_android,"glBindBuffer"); disp->set_glBindBuffer((glBindBuffer_t)ptr);
+ ptr = dlsym(gles_android,"glBindTexture"); disp->set_glBindTexture((glBindTexture_t)ptr);
+ ptr = dlsym(gles_android,"glBlendFunc"); disp->set_glBlendFunc((glBlendFunc_t)ptr);
+ ptr = dlsym(gles_android,"glBufferData"); disp->set_glBufferData((glBufferData_t)ptr);
+ ptr = dlsym(gles_android,"glBufferSubData"); disp->set_glBufferSubData((glBufferSubData_t)ptr);
+ ptr = dlsym(gles_android,"glClear"); disp->set_glClear((glClear_t)ptr);
+ ptr = dlsym(gles_android,"glClearColorx"); disp->set_glClearColorx((glClearColorx_t)ptr);
+ ptr = dlsym(gles_android,"glClearDepthx"); disp->set_glClearDepthx((glClearDepthx_t)ptr);
+ ptr = dlsym(gles_android,"glClearStencil"); disp->set_glClearStencil((glClearStencil_t)ptr);
+ ptr = dlsym(gles_android,"glClientActiveTexture"); disp->set_glClientActiveTexture((glClientActiveTexture_t)ptr);
+ ptr = dlsym(gles_android,"glClipPlanex"); disp->set_glClipPlanex((glClipPlanex_t)ptr);
+ ptr = dlsym(gles_android,"glColor4ub"); disp->set_glColor4ub((glColor4ub_t)ptr);
+ ptr = dlsym(gles_android,"glColor4x"); disp->set_glColor4x((glColor4x_t)ptr);
+ ptr = dlsym(gles_android,"glColorMask"); disp->set_glColorMask((glColorMask_t)ptr);
+ ptr = dlsym(gles_android,"glColorPointer"); disp->set_glColorPointer((glColorPointer_t)ptr);
+ ptr = dlsym(gles_android,"glCompressedTexImage2D"); disp->set_glCompressedTexImage2D((glCompressedTexImage2D_t)ptr);
+ ptr = dlsym(gles_android,"glCompressedTexSubImage2D"); disp->set_glCompressedTexSubImage2D((glCompressedTexSubImage2D_t)ptr);
+ ptr = dlsym(gles_android,"glCopyTexImage2D"); disp->set_glCopyTexImage2D((glCopyTexImage2D_t)ptr);
+ ptr = dlsym(gles_android,"glCopyTexSubImage2D"); disp->set_glCopyTexSubImage2D((glCopyTexSubImage2D_t)ptr);
+ ptr = dlsym(gles_android,"glCullFace"); disp->set_glCullFace((glCullFace_t)ptr);
+ ptr = dlsym(gles_android,"glDeleteBuffers"); disp->set_glDeleteBuffers((glDeleteBuffers_t)ptr);
+ ptr = dlsym(gles_android,"glDeleteTextures"); disp->set_glDeleteTextures((glDeleteTextures_t)ptr);
+ ptr = dlsym(gles_android,"glDepthFunc"); disp->set_glDepthFunc((glDepthFunc_t)ptr);
+ ptr = dlsym(gles_android,"glDepthMask"); disp->set_glDepthMask((glDepthMask_t)ptr);
+ ptr = dlsym(gles_android,"glDepthRangex"); disp->set_glDepthRangex((glDepthRangex_t)ptr);
+ ptr = dlsym(gles_android,"glDisable"); disp->set_glDisable((glDisable_t)ptr);
+ ptr = dlsym(gles_android,"glDisableClientState"); disp->set_glDisableClientState((glDisableClientState_t)ptr);
+ ptr = dlsym(gles_android,"glDrawArrays"); disp->set_glDrawArrays((glDrawArrays_t)ptr);
+ ptr = dlsym(gles_android,"glDrawElements"); disp->set_glDrawElements((glDrawElements_t)ptr);
+ ptr = dlsym(gles_android,"glEnable"); disp->set_glEnable((glEnable_t)ptr);
+ ptr = dlsym(gles_android,"glEnableClientState"); disp->set_glEnableClientState((glEnableClientState_t)ptr);
+ ptr = dlsym(gles_android,"glFinish"); disp->set_glFinish((glFinish_t)ptr);
+ ptr = dlsym(gles_android,"glFlush"); disp->set_glFlush((glFlush_t)ptr);
+ ptr = dlsym(gles_android,"glFogx"); disp->set_glFogx((glFogx_t)ptr);
+ ptr = dlsym(gles_android,"glFogxv"); disp->set_glFogxv((glFogxv_t)ptr);
+ ptr = dlsym(gles_android,"glFrontFace"); disp->set_glFrontFace((glFrontFace_t)ptr);
+ ptr = dlsym(gles_android,"glFrustumx"); disp->set_glFrustumx((glFrustumx_t)ptr);
+ ptr = dlsym(gles_android,"glGetBooleanv"); disp->set_glGetBooleanv((glGetBooleanv_t)ptr);
+ ptr = dlsym(gles_android,"glGetBufferParameteriv"); disp->set_glGetBufferParameteriv((glGetBufferParameteriv_t)ptr);
+ ptr = dlsym(gles_android,"glGetClipPlanex"); disp->set_glGetClipPlanex((glGetClipPlanex_t)ptr);
+ ptr = dlsym(gles_android,"glGenBuffers"); disp->set_glGenBuffers((glGenBuffers_t)ptr);
+ ptr = dlsym(gles_android,"glGenTextures"); disp->set_glGenTextures((glGenTextures_t)ptr);
+ ptr = dlsym(gles_android,"glGetError"); disp->set_glGetError((glGetError_t)ptr);
+ ptr = dlsym(gles_android,"glGetFixedv"); disp->set_glGetFixedv((glGetFixedv_t)ptr);
+ ptr = dlsym(gles_android,"glGetIntegerv"); disp->set_glGetIntegerv((glGetIntegerv_t)ptr);
+ ptr = dlsym(gles_android,"glGetLightxv"); disp->set_glGetLightxv((glGetLightxv_t)ptr);
+ ptr = dlsym(gles_android,"glGetMaterialxv"); disp->set_glGetMaterialxv((glGetMaterialxv_t)ptr);
+ ptr = dlsym(gles_android,"glGetPointerv"); disp->set_glGetPointerv((glGetPointerv_t)ptr);
+ ptr = dlsym(gles_android,"glGetString"); disp->set_glGetString((glGetString_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexEnviv"); disp->set_glGetTexEnviv((glGetTexEnviv_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexEnvxv"); disp->set_glGetTexEnvxv((glGetTexEnvxv_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexParameteriv"); disp->set_glGetTexParameteriv((glGetTexParameteriv_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexParameterxv"); disp->set_glGetTexParameterxv((glGetTexParameterxv_t)ptr);
+ ptr = dlsym(gles_android,"glHint"); disp->set_glHint((glHint_t)ptr);
+ ptr = dlsym(gles_android,"glIsBuffer"); disp->set_glIsBuffer((glIsBuffer_t)ptr);
+ ptr = dlsym(gles_android,"glIsEnabled"); disp->set_glIsEnabled((glIsEnabled_t)ptr);
+ ptr = dlsym(gles_android,"glIsTexture"); disp->set_glIsTexture((glIsTexture_t)ptr);
+ ptr = dlsym(gles_android,"glLightModelx"); disp->set_glLightModelx((glLightModelx_t)ptr);
+ ptr = dlsym(gles_android,"glLightModelxv"); disp->set_glLightModelxv((glLightModelxv_t)ptr);
+ ptr = dlsym(gles_android,"glLightx"); disp->set_glLightx((glLightx_t)ptr);
+ ptr = dlsym(gles_android,"glLightxv"); disp->set_glLightxv((glLightxv_t)ptr);
+ ptr = dlsym(gles_android,"glLineWidthx"); disp->set_glLineWidthx((glLineWidthx_t)ptr);
+ ptr = dlsym(gles_android,"glLoadIdentity"); disp->set_glLoadIdentity((glLoadIdentity_t)ptr);
+ ptr = dlsym(gles_android,"glLoadMatrixx"); disp->set_glLoadMatrixx((glLoadMatrixx_t)ptr);
+ ptr = dlsym(gles_android,"glLogicOp"); disp->set_glLogicOp((glLogicOp_t)ptr);
+ ptr = dlsym(gles_android,"glMaterialx"); disp->set_glMaterialx((glMaterialx_t)ptr);
+ ptr = dlsym(gles_android,"glMaterialxv"); disp->set_glMaterialxv((glMaterialxv_t)ptr);
+ ptr = dlsym(gles_android,"glMatrixMode"); disp->set_glMatrixMode((glMatrixMode_t)ptr);
+ ptr = dlsym(gles_android,"glMultMatrixx"); disp->set_glMultMatrixx((glMultMatrixx_t)ptr);
+ ptr = dlsym(gles_android,"glMultiTexCoord4x"); disp->set_glMultiTexCoord4x((glMultiTexCoord4x_t)ptr);
+ ptr = dlsym(gles_android,"glNormal3x"); disp->set_glNormal3x((glNormal3x_t)ptr);
+ ptr = dlsym(gles_android,"glNormalPointer"); disp->set_glNormalPointer((glNormalPointer_t)ptr);
+ ptr = dlsym(gles_android,"glOrthox"); disp->set_glOrthox((glOrthox_t)ptr);
+ ptr = dlsym(gles_android,"glPixelStorei"); disp->set_glPixelStorei((glPixelStorei_t)ptr);
+ ptr = dlsym(gles_android,"glPointParameterx"); disp->set_glPointParameterx((glPointParameterx_t)ptr);
+ ptr = dlsym(gles_android,"glPointParameterxv"); disp->set_glPointParameterxv((glPointParameterxv_t)ptr);
+ ptr = dlsym(gles_android,"glPointSizex"); disp->set_glPointSizex((glPointSizex_t)ptr);
+ ptr = dlsym(gles_android,"glPolygonOffsetx"); disp->set_glPolygonOffsetx((glPolygonOffsetx_t)ptr);
+ ptr = dlsym(gles_android,"glPopMatrix"); disp->set_glPopMatrix((glPopMatrix_t)ptr);
+ ptr = dlsym(gles_android,"glPushMatrix"); disp->set_glPushMatrix((glPushMatrix_t)ptr);
+ ptr = dlsym(gles_android,"glReadPixels"); disp->set_glReadPixels((glReadPixels_t)ptr);
+ ptr = dlsym(gles_android,"glRotatex"); disp->set_glRotatex((glRotatex_t)ptr);
+ ptr = dlsym(gles_android,"glSampleCoverage"); disp->set_glSampleCoverage((glSampleCoverage_t)ptr);
+ ptr = dlsym(gles_android,"glSampleCoveragex"); disp->set_glSampleCoveragex((glSampleCoveragex_t)ptr);
+ ptr = dlsym(gles_android,"glScalex"); disp->set_glScalex((glScalex_t)ptr);
+ ptr = dlsym(gles_android,"glScissor"); disp->set_glScissor((glScissor_t)ptr);
+ ptr = dlsym(gles_android,"glShadeModel"); disp->set_glShadeModel((glShadeModel_t)ptr);
+ ptr = dlsym(gles_android,"glStencilFunc"); disp->set_glStencilFunc((glStencilFunc_t)ptr);
+ ptr = dlsym(gles_android,"glStencilMask"); disp->set_glStencilMask((glStencilMask_t)ptr);
+ ptr = dlsym(gles_android,"glStencilOp"); disp->set_glStencilOp((glStencilOp_t)ptr);
+ ptr = dlsym(gles_android,"glTexCoordPointer"); disp->set_glTexCoordPointer((glTexCoordPointer_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnvi"); disp->set_glTexEnvi((glTexEnvi_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnvx"); disp->set_glTexEnvx((glTexEnvx_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnviv"); disp->set_glTexEnviv((glTexEnviv_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnvxv"); disp->set_glTexEnvxv((glTexEnvxv_t)ptr);
+ ptr = dlsym(gles_android,"glTexImage2D"); disp->set_glTexImage2D((glTexImage2D_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameteri"); disp->set_glTexParameteri((glTexParameteri_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameterx"); disp->set_glTexParameterx((glTexParameterx_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameteriv"); disp->set_glTexParameteriv((glTexParameteriv_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameterxv"); disp->set_glTexParameterxv((glTexParameterxv_t)ptr);
+ ptr = dlsym(gles_android,"glTexSubImage2D"); disp->set_glTexSubImage2D((glTexSubImage2D_t)ptr);
+ ptr = dlsym(gles_android,"glTranslatex"); disp->set_glTranslatex((glTranslatex_t)ptr);
+ ptr = dlsym(gles_android,"glVertexPointer"); disp->set_glVertexPointer((glVertexPointer_t)ptr);
+ ptr = dlsym(gles_android,"glViewport"); disp->set_glViewport((glViewport_t)ptr);
+ ptr = dlsym(gles_android,"glPointSizePointerOES"); disp->set_glPointSizePointerOES((glPointSizePointerOES_t)ptr);
+ ptr = dlsym(gles_android,"glBlendEquationSeparateOES"); disp->set_glBlendEquationSeparateOES((glBlendEquationSeparateOES_t)ptr);
+ ptr = dlsym(gles_android,"glBlendFuncSeparateOES"); disp->set_glBlendFuncSeparateOES((glBlendFuncSeparateOES_t)ptr);
+ ptr = dlsym(gles_android,"glBlendEquationOES"); disp->set_glBlendEquationOES((glBlendEquationOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexsOES"); disp->set_glDrawTexsOES((glDrawTexsOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexiOES"); disp->set_glDrawTexiOES((glDrawTexiOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexxOES"); disp->set_glDrawTexxOES((glDrawTexxOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexsvOES"); disp->set_glDrawTexsvOES((glDrawTexsvOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexivOES"); disp->set_glDrawTexivOES((glDrawTexivOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexxvOES"); disp->set_glDrawTexxvOES((glDrawTexxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexfOES"); disp->set_glDrawTexfOES((glDrawTexfOES_t)ptr);
+ ptr = dlsym(gles_android,"glDrawTexfvOES"); disp->set_glDrawTexfvOES((glDrawTexfvOES_t)ptr);
+ ptr = dlsym(gles_android,"glEGLImageTargetTexture2DOES"); disp->set_glEGLImageTargetTexture2DOES((glEGLImageTargetTexture2DOES_t)ptr);
+ ptr = dlsym(gles_android,"glEGLImageTargetRenderbufferStorageOES"); disp->set_glEGLImageTargetRenderbufferStorageOES((glEGLImageTargetRenderbufferStorageOES_t)ptr);
+ ptr = dlsym(gles_android,"glAlphaFuncxOES"); disp->set_glAlphaFuncxOES((glAlphaFuncxOES_t)ptr);
+ ptr = dlsym(gles_android,"glClearColorxOES"); disp->set_glClearColorxOES((glClearColorxOES_t)ptr);
+ ptr = dlsym(gles_android,"glClearDepthxOES"); disp->set_glClearDepthxOES((glClearDepthxOES_t)ptr);
+ ptr = dlsym(gles_android,"glClipPlanexOES"); disp->set_glClipPlanexOES((glClipPlanexOES_t)ptr);
+ ptr = dlsym(gles_android,"glColor4xOES"); disp->set_glColor4xOES((glColor4xOES_t)ptr);
+ ptr = dlsym(gles_android,"glDepthRangexOES"); disp->set_glDepthRangexOES((glDepthRangexOES_t)ptr);
+ ptr = dlsym(gles_android,"glFogxOES"); disp->set_glFogxOES((glFogxOES_t)ptr);
+ ptr = dlsym(gles_android,"glFogxvOES"); disp->set_glFogxvOES((glFogxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glFrustumxOES"); disp->set_glFrustumxOES((glFrustumxOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetClipPlanexOES"); disp->set_glGetClipPlanexOES((glGetClipPlanexOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetFixedvOES"); disp->set_glGetFixedvOES((glGetFixedvOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetLightxvOES"); disp->set_glGetLightxvOES((glGetLightxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetMaterialxvOES"); disp->set_glGetMaterialxvOES((glGetMaterialxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexEnvxvOES"); disp->set_glGetTexEnvxvOES((glGetTexEnvxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexParameterxvOES"); disp->set_glGetTexParameterxvOES((glGetTexParameterxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glLightModelxOES"); disp->set_glLightModelxOES((glLightModelxOES_t)ptr);
+ ptr = dlsym(gles_android,"glLightModelxvOES"); disp->set_glLightModelxvOES((glLightModelxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glLightxOES"); disp->set_glLightxOES((glLightxOES_t)ptr);
+ ptr = dlsym(gles_android,"glLightxvOES"); disp->set_glLightxvOES((glLightxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glLineWidthxOES"); disp->set_glLineWidthxOES((glLineWidthxOES_t)ptr);
+ ptr = dlsym(gles_android,"glLoadMatrixxOES"); disp->set_glLoadMatrixxOES((glLoadMatrixxOES_t)ptr);
+ ptr = dlsym(gles_android,"glMaterialxOES"); disp->set_glMaterialxOES((glMaterialxOES_t)ptr);
+ ptr = dlsym(gles_android,"glMaterialxvOES"); disp->set_glMaterialxvOES((glMaterialxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glMultMatrixxOES"); disp->set_glMultMatrixxOES((glMultMatrixxOES_t)ptr);
+ ptr = dlsym(gles_android,"glMultiTexCoord4xOES"); disp->set_glMultiTexCoord4xOES((glMultiTexCoord4xOES_t)ptr);
+ ptr = dlsym(gles_android,"glNormal3xOES"); disp->set_glNormal3xOES((glNormal3xOES_t)ptr);
+ ptr = dlsym(gles_android,"glOrthoxOES"); disp->set_glOrthoxOES((glOrthoxOES_t)ptr);
+ ptr = dlsym(gles_android,"glPointParameterxOES"); disp->set_glPointParameterxOES((glPointParameterxOES_t)ptr);
+ ptr = dlsym(gles_android,"glPointParameterxvOES"); disp->set_glPointParameterxvOES((glPointParameterxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glPointSizexOES"); disp->set_glPointSizexOES((glPointSizexOES_t)ptr);
+ ptr = dlsym(gles_android,"glPolygonOffsetxOES"); disp->set_glPolygonOffsetxOES((glPolygonOffsetxOES_t)ptr);
+ ptr = dlsym(gles_android,"glRotatexOES"); disp->set_glRotatexOES((glRotatexOES_t)ptr);
+ ptr = dlsym(gles_android,"glSampleCoveragexOES"); disp->set_glSampleCoveragexOES((glSampleCoveragexOES_t)ptr);
+ ptr = dlsym(gles_android,"glScalexOES"); disp->set_glScalexOES((glScalexOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnvxOES"); disp->set_glTexEnvxOES((glTexEnvxOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexEnvxvOES"); disp->set_glTexEnvxvOES((glTexEnvxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameterxOES"); disp->set_glTexParameterxOES((glTexParameterxOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexParameterxvOES"); disp->set_glTexParameterxvOES((glTexParameterxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glTranslatexOES"); disp->set_glTranslatexOES((glTranslatexOES_t)ptr);
+ ptr = dlsym(gles_android,"glIsRenderbufferOES"); disp->set_glIsRenderbufferOES((glIsRenderbufferOES_t)ptr);
+ ptr = dlsym(gles_android,"glBindRenderbufferOES"); disp->set_glBindRenderbufferOES((glBindRenderbufferOES_t)ptr);
+ ptr = dlsym(gles_android,"glDeleteRenderbuffersOES"); disp->set_glDeleteRenderbuffersOES((glDeleteRenderbuffersOES_t)ptr);
+ ptr = dlsym(gles_android,"glGenRenderbuffersOES"); disp->set_glGenRenderbuffersOES((glGenRenderbuffersOES_t)ptr);
+ ptr = dlsym(gles_android,"glRenderbufferStorageOES"); disp->set_glRenderbufferStorageOES((glRenderbufferStorageOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetRenderbufferParameterivOES"); disp->set_glGetRenderbufferParameterivOES((glGetRenderbufferParameterivOES_t)ptr);
+ ptr = dlsym(gles_android,"glIsFramebufferOES"); disp->set_glIsFramebufferOES((glIsFramebufferOES_t)ptr);
+ ptr = dlsym(gles_android,"glBindFramebufferOES"); disp->set_glBindFramebufferOES((glBindFramebufferOES_t)ptr);
+ ptr = dlsym(gles_android,"glDeleteFramebuffersOES"); disp->set_glDeleteFramebuffersOES((glDeleteFramebuffersOES_t)ptr);
+ ptr = dlsym(gles_android,"glGenFramebuffersOES"); disp->set_glGenFramebuffersOES((glGenFramebuffersOES_t)ptr);
+ ptr = dlsym(gles_android,"glCheckFramebufferStatusOES"); disp->set_glCheckFramebufferStatusOES((glCheckFramebufferStatusOES_t)ptr);
+ ptr = dlsym(gles_android,"glFramebufferRenderbufferOES"); disp->set_glFramebufferRenderbufferOES((glFramebufferRenderbufferOES_t)ptr);
+ ptr = dlsym(gles_android,"glFramebufferTexture2DOES"); disp->set_glFramebufferTexture2DOES((glFramebufferTexture2DOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetFramebufferAttachmentParameterivOES"); disp->set_glGetFramebufferAttachmentParameterivOES((glGetFramebufferAttachmentParameterivOES_t)ptr);
+ ptr = dlsym(gles_android,"glGenerateMipmapOES"); disp->set_glGenerateMipmapOES((glGenerateMipmapOES_t)ptr);
+ ptr = dlsym(gles_android,"glMapBufferOES"); disp->set_glMapBufferOES((glMapBufferOES_t)ptr);
+ ptr = dlsym(gles_android,"glUnmapBufferOES"); disp->set_glUnmapBufferOES((glUnmapBufferOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetBufferPointervOES"); disp->set_glGetBufferPointervOES((glGetBufferPointervOES_t)ptr);
+ ptr = dlsym(gles_android,"glCurrentPaletteMatrixOES"); disp->set_glCurrentPaletteMatrixOES((glCurrentPaletteMatrixOES_t)ptr);
+ ptr = dlsym(gles_android,"glLoadPaletteFromModelViewMatrixOES"); disp->set_glLoadPaletteFromModelViewMatrixOES((glLoadPaletteFromModelViewMatrixOES_t)ptr);
+ ptr = dlsym(gles_android,"glMatrixIndexPointerOES"); disp->set_glMatrixIndexPointerOES((glMatrixIndexPointerOES_t)ptr);
+ ptr = dlsym(gles_android,"glWeightPointerOES"); disp->set_glWeightPointerOES((glWeightPointerOES_t)ptr);
+ ptr = dlsym(gles_android,"glQueryMatrixxOES"); disp->set_glQueryMatrixxOES((glQueryMatrixxOES_t)ptr);
+ ptr = dlsym(gles_android,"glDepthRangefOES"); disp->set_glDepthRangefOES((glDepthRangefOES_t)ptr);
+ ptr = dlsym(gles_android,"glFrustumfOES"); disp->set_glFrustumfOES((glFrustumfOES_t)ptr);
+ ptr = dlsym(gles_android,"glOrthofOES"); disp->set_glOrthofOES((glOrthofOES_t)ptr);
+ ptr = dlsym(gles_android,"glClipPlanefOES"); disp->set_glClipPlanefOES((glClipPlanefOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetClipPlanefOES"); disp->set_glGetClipPlanefOES((glGetClipPlanefOES_t)ptr);
+ ptr = dlsym(gles_android,"glClearDepthfOES"); disp->set_glClearDepthfOES((glClearDepthfOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexGenfOES"); disp->set_glTexGenfOES((glTexGenfOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexGenfvOES"); disp->set_glTexGenfvOES((glTexGenfvOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexGeniOES"); disp->set_glTexGeniOES((glTexGeniOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexGenivOES"); disp->set_glTexGenivOES((glTexGenivOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexGenxOES"); disp->set_glTexGenxOES((glTexGenxOES_t)ptr);
+ ptr = dlsym(gles_android,"glTexGenxvOES"); disp->set_glTexGenxvOES((glTexGenxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexGenfvOES"); disp->set_glGetTexGenfvOES((glGetTexGenfvOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexGenivOES"); disp->set_glGetTexGenivOES((glGetTexGenivOES_t)ptr);
+ ptr = dlsym(gles_android,"glGetTexGenxvOES"); disp->set_glGetTexGenxvOES((glGetTexGenxvOES_t)ptr);
+ ptr = dlsym(gles_android,"glBindVertexArrayOES"); disp->set_glBindVertexArrayOES((glBindVertexArrayOES_t)ptr);
+ ptr = dlsym(gles_android,"glDeleteVertexArraysOES"); disp->set_glDeleteVertexArraysOES((glDeleteVertexArraysOES_t)ptr);
+ ptr = dlsym(gles_android,"glGenVertexArraysOES"); disp->set_glGenVertexArraysOES((glGenVertexArraysOES_t)ptr);
+ ptr = dlsym(gles_android,"glIsVertexArrayOES"); disp->set_glIsVertexArrayOES((glIsVertexArrayOES_t)ptr);
+ ptr = dlsym(gles_android,"glDiscardFramebufferEXT"); disp->set_glDiscardFramebufferEXT((glDiscardFramebufferEXT_t)ptr);
+ ptr = dlsym(gles_android,"glMultiDrawArraysEXT"); disp->set_glMultiDrawArraysEXT((glMultiDrawArraysEXT_t)ptr);
+ ptr = dlsym(gles_android,"glMultiDrawElementsEXT"); disp->set_glMultiDrawElementsEXT((glMultiDrawElementsEXT_t)ptr);
+ ptr = dlsym(gles_android,"glClipPlanefIMG"); disp->set_glClipPlanefIMG((glClipPlanefIMG_t)ptr);
+ ptr = dlsym(gles_android,"glClipPlanexIMG"); disp->set_glClipPlanexIMG((glClipPlanexIMG_t)ptr);
+ ptr = dlsym(gles_android,"glRenderbufferStorageMultisampleIMG"); disp->set_glRenderbufferStorageMultisampleIMG((glRenderbufferStorageMultisampleIMG_t)ptr);
+ ptr = dlsym(gles_android,"glFramebufferTexture2DMultisampleIMG"); disp->set_glFramebufferTexture2DMultisampleIMG((glFramebufferTexture2DMultisampleIMG_t)ptr);
+ ptr = dlsym(gles_android,"glDeleteFencesNV"); disp->set_glDeleteFencesNV((glDeleteFencesNV_t)ptr);
+ ptr = dlsym(gles_android,"glGenFencesNV"); disp->set_glGenFencesNV((glGenFencesNV_t)ptr);
+ ptr = dlsym(gles_android,"glIsFenceNV"); disp->set_glIsFenceNV((glIsFenceNV_t)ptr);
+ ptr = dlsym(gles_android,"glTestFenceNV"); disp->set_glTestFenceNV((glTestFenceNV_t)ptr);
+ ptr = dlsym(gles_android,"glGetFenceivNV"); disp->set_glGetFenceivNV((glGetFenceivNV_t)ptr);
+ ptr = dlsym(gles_android,"glFinishFenceNV"); disp->set_glFinishFenceNV((glFinishFenceNV_t)ptr);
+ ptr = dlsym(gles_android,"glSetFenceNV"); disp->set_glSetFenceNV((glSetFenceNV_t)ptr);
+ ptr = dlsym(gles_android,"glGetDriverControlsQCOM"); disp->set_glGetDriverControlsQCOM((glGetDriverControlsQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glGetDriverControlStringQCOM"); disp->set_glGetDriverControlStringQCOM((glGetDriverControlStringQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glEnableDriverControlQCOM"); disp->set_glEnableDriverControlQCOM((glEnableDriverControlQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glDisableDriverControlQCOM"); disp->set_glDisableDriverControlQCOM((glDisableDriverControlQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetTexturesQCOM"); disp->set_glExtGetTexturesQCOM((glExtGetTexturesQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetBuffersQCOM"); disp->set_glExtGetBuffersQCOM((glExtGetBuffersQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetRenderbuffersQCOM"); disp->set_glExtGetRenderbuffersQCOM((glExtGetRenderbuffersQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetFramebuffersQCOM"); disp->set_glExtGetFramebuffersQCOM((glExtGetFramebuffersQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetTexLevelParameterivQCOM"); disp->set_glExtGetTexLevelParameterivQCOM((glExtGetTexLevelParameterivQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtTexObjectStateOverrideiQCOM"); disp->set_glExtTexObjectStateOverrideiQCOM((glExtTexObjectStateOverrideiQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetTexSubImageQCOM"); disp->set_glExtGetTexSubImageQCOM((glExtGetTexSubImageQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetBufferPointervQCOM"); disp->set_glExtGetBufferPointervQCOM((glExtGetBufferPointervQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetShadersQCOM"); disp->set_glExtGetShadersQCOM((glExtGetShadersQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetProgramsQCOM"); disp->set_glExtGetProgramsQCOM((glExtGetProgramsQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtIsProgramBinaryQCOM"); disp->set_glExtIsProgramBinaryQCOM((glExtIsProgramBinaryQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glExtGetProgramBinarySourceQCOM"); disp->set_glExtGetProgramBinarySourceQCOM((glExtGetProgramBinarySourceQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glStartTilingQCOM"); disp->set_glStartTilingQCOM((glStartTilingQCOM_t)ptr);
+ ptr = dlsym(gles_android,"glEndTilingQCOM"); disp->set_glEndTilingQCOM((glEndTilingQCOM_t)ptr);
+
+ return disp;
+}
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/gles_dispatch.h b/tools/emulator/opengl/tests/gles_android_wrapper/gles_dispatch.h
new file mode 100644
index 0000000..98a4fca
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/gles_dispatch.h
@@ -0,0 +1,570 @@
+/*
+* 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.
+*/
+#ifndef _GLES_DISPATCH_H
+#define _GLES_DISPATCH_H
+
+#include "gles_proc.h"
+
+
+struct gles_dispatch {
+ glAlphaFunc_t glAlphaFunc;
+ glClearColor_t glClearColor;
+ glClearDepthf_t glClearDepthf;
+ glClipPlanef_t glClipPlanef;
+ glColor4f_t glColor4f;
+ glDepthRangef_t glDepthRangef;
+ glFogf_t glFogf;
+ glFogfv_t glFogfv;
+ glFrustumf_t glFrustumf;
+ glGetClipPlanef_t glGetClipPlanef;
+ glGetFloatv_t glGetFloatv;
+ glGetLightfv_t glGetLightfv;
+ glGetMaterialfv_t glGetMaterialfv;
+ glGetTexEnvfv_t glGetTexEnvfv;
+ glGetTexParameterfv_t glGetTexParameterfv;
+ glLightModelf_t glLightModelf;
+ glLightModelfv_t glLightModelfv;
+ glLightf_t glLightf;
+ glLightfv_t glLightfv;
+ glLineWidth_t glLineWidth;
+ glLoadMatrixf_t glLoadMatrixf;
+ glMaterialf_t glMaterialf;
+ glMaterialfv_t glMaterialfv;
+ glMultMatrixf_t glMultMatrixf;
+ glMultiTexCoord4f_t glMultiTexCoord4f;
+ glNormal3f_t glNormal3f;
+ glOrthof_t glOrthof;
+ glPointParameterf_t glPointParameterf;
+ glPointParameterfv_t glPointParameterfv;
+ glPointSize_t glPointSize;
+ glPolygonOffset_t glPolygonOffset;
+ glRotatef_t glRotatef;
+ glScalef_t glScalef;
+ glTexEnvf_t glTexEnvf;
+ glTexEnvfv_t glTexEnvfv;
+ glTexParameterf_t glTexParameterf;
+ glTexParameterfv_t glTexParameterfv;
+ glTranslatef_t glTranslatef;
+ glActiveTexture_t glActiveTexture;
+ glAlphaFuncx_t glAlphaFuncx;
+ glBindBuffer_t glBindBuffer;
+ glBindTexture_t glBindTexture;
+ glBlendFunc_t glBlendFunc;
+ glBufferData_t glBufferData;
+ glBufferSubData_t glBufferSubData;
+ glClear_t glClear;
+ glClearColorx_t glClearColorx;
+ glClearDepthx_t glClearDepthx;
+ glClearStencil_t glClearStencil;
+ glClientActiveTexture_t glClientActiveTexture;
+ glClipPlanex_t glClipPlanex;
+ glColor4ub_t glColor4ub;
+ glColor4x_t glColor4x;
+ glColorMask_t glColorMask;
+ glColorPointer_t glColorPointer;
+ glCompressedTexImage2D_t glCompressedTexImage2D;
+ glCompressedTexSubImage2D_t glCompressedTexSubImage2D;
+ glCopyTexImage2D_t glCopyTexImage2D;
+ glCopyTexSubImage2D_t glCopyTexSubImage2D;
+ glCullFace_t glCullFace;
+ glDeleteBuffers_t glDeleteBuffers;
+ glDeleteTextures_t glDeleteTextures;
+ glDepthFunc_t glDepthFunc;
+ glDepthMask_t glDepthMask;
+ glDepthRangex_t glDepthRangex;
+ glDisable_t glDisable;
+ glDisableClientState_t glDisableClientState;
+ glDrawArrays_t glDrawArrays;
+ glDrawElements_t glDrawElements;
+ glEnable_t glEnable;
+ glEnableClientState_t glEnableClientState;
+ glFinish_t glFinish;
+ glFlush_t glFlush;
+ glFogx_t glFogx;
+ glFogxv_t glFogxv;
+ glFrontFace_t glFrontFace;
+ glFrustumx_t glFrustumx;
+ glGetBooleanv_t glGetBooleanv;
+ glGetBufferParameteriv_t glGetBufferParameteriv;
+ glGetClipPlanex_t glGetClipPlanex;
+ glGenBuffers_t glGenBuffers;
+ glGenTextures_t glGenTextures;
+ glGetError_t glGetError;
+ glGetFixedv_t glGetFixedv;
+ glGetIntegerv_t glGetIntegerv;
+ glGetLightxv_t glGetLightxv;
+ glGetMaterialxv_t glGetMaterialxv;
+ glGetPointerv_t glGetPointerv;
+ glGetString_t glGetString;
+ glGetTexEnviv_t glGetTexEnviv;
+ glGetTexEnvxv_t glGetTexEnvxv;
+ glGetTexParameteriv_t glGetTexParameteriv;
+ glGetTexParameterxv_t glGetTexParameterxv;
+ glHint_t glHint;
+ glIsBuffer_t glIsBuffer;
+ glIsEnabled_t glIsEnabled;
+ glIsTexture_t glIsTexture;
+ glLightModelx_t glLightModelx;
+ glLightModelxv_t glLightModelxv;
+ glLightx_t glLightx;
+ glLightxv_t glLightxv;
+ glLineWidthx_t glLineWidthx;
+ glLoadIdentity_t glLoadIdentity;
+ glLoadMatrixx_t glLoadMatrixx;
+ glLogicOp_t glLogicOp;
+ glMaterialx_t glMaterialx;
+ glMaterialxv_t glMaterialxv;
+ glMatrixMode_t glMatrixMode;
+ glMultMatrixx_t glMultMatrixx;
+ glMultiTexCoord4x_t glMultiTexCoord4x;
+ glNormal3x_t glNormal3x;
+ glNormalPointer_t glNormalPointer;
+ glOrthox_t glOrthox;
+ glPixelStorei_t glPixelStorei;
+ glPointParameterx_t glPointParameterx;
+ glPointParameterxv_t glPointParameterxv;
+ glPointSizex_t glPointSizex;
+ glPolygonOffsetx_t glPolygonOffsetx;
+ glPopMatrix_t glPopMatrix;
+ glPushMatrix_t glPushMatrix;
+ glReadPixels_t glReadPixels;
+ glRotatex_t glRotatex;
+ glSampleCoverage_t glSampleCoverage;
+ glSampleCoveragex_t glSampleCoveragex;
+ glScalex_t glScalex;
+ glScissor_t glScissor;
+ glShadeModel_t glShadeModel;
+ glStencilFunc_t glStencilFunc;
+ glStencilMask_t glStencilMask;
+ glStencilOp_t glStencilOp;
+ glTexCoordPointer_t glTexCoordPointer;
+ glTexEnvi_t glTexEnvi;
+ glTexEnvx_t glTexEnvx;
+ glTexEnviv_t glTexEnviv;
+ glTexEnvxv_t glTexEnvxv;
+ glTexImage2D_t glTexImage2D;
+ glTexParameteri_t glTexParameteri;
+ glTexParameterx_t glTexParameterx;
+ glTexParameteriv_t glTexParameteriv;
+ glTexParameterxv_t glTexParameterxv;
+ glTexSubImage2D_t glTexSubImage2D;
+ glTranslatex_t glTranslatex;
+ glVertexPointer_t glVertexPointer;
+ glViewport_t glViewport;
+ glPointSizePointerOES_t glPointSizePointerOES;
+ glBlendEquationSeparateOES_t glBlendEquationSeparateOES;
+ glBlendFuncSeparateOES_t glBlendFuncSeparateOES;
+ glBlendEquationOES_t glBlendEquationOES;
+ glDrawTexsOES_t glDrawTexsOES;
+ glDrawTexiOES_t glDrawTexiOES;
+ glDrawTexxOES_t glDrawTexxOES;
+ glDrawTexsvOES_t glDrawTexsvOES;
+ glDrawTexivOES_t glDrawTexivOES;
+ glDrawTexxvOES_t glDrawTexxvOES;
+ glDrawTexfOES_t glDrawTexfOES;
+ glDrawTexfvOES_t glDrawTexfvOES;
+ glEGLImageTargetTexture2DOES_t glEGLImageTargetTexture2DOES;
+ glEGLImageTargetRenderbufferStorageOES_t glEGLImageTargetRenderbufferStorageOES;
+ glAlphaFuncxOES_t glAlphaFuncxOES;
+ glClearColorxOES_t glClearColorxOES;
+ glClearDepthxOES_t glClearDepthxOES;
+ glClipPlanexOES_t glClipPlanexOES;
+ glColor4xOES_t glColor4xOES;
+ glDepthRangexOES_t glDepthRangexOES;
+ glFogxOES_t glFogxOES;
+ glFogxvOES_t glFogxvOES;
+ glFrustumxOES_t glFrustumxOES;
+ glGetClipPlanexOES_t glGetClipPlanexOES;
+ glGetFixedvOES_t glGetFixedvOES;
+ glGetLightxvOES_t glGetLightxvOES;
+ glGetMaterialxvOES_t glGetMaterialxvOES;
+ glGetTexEnvxvOES_t glGetTexEnvxvOES;
+ glGetTexParameterxvOES_t glGetTexParameterxvOES;
+ glLightModelxOES_t glLightModelxOES;
+ glLightModelxvOES_t glLightModelxvOES;
+ glLightxOES_t glLightxOES;
+ glLightxvOES_t glLightxvOES;
+ glLineWidthxOES_t glLineWidthxOES;
+ glLoadMatrixxOES_t glLoadMatrixxOES;
+ glMaterialxOES_t glMaterialxOES;
+ glMaterialxvOES_t glMaterialxvOES;
+ glMultMatrixxOES_t glMultMatrixxOES;
+ glMultiTexCoord4xOES_t glMultiTexCoord4xOES;
+ glNormal3xOES_t glNormal3xOES;
+ glOrthoxOES_t glOrthoxOES;
+ glPointParameterxOES_t glPointParameterxOES;
+ glPointParameterxvOES_t glPointParameterxvOES;
+ glPointSizexOES_t glPointSizexOES;
+ glPolygonOffsetxOES_t glPolygonOffsetxOES;
+ glRotatexOES_t glRotatexOES;
+ glSampleCoveragexOES_t glSampleCoveragexOES;
+ glScalexOES_t glScalexOES;
+ glTexEnvxOES_t glTexEnvxOES;
+ glTexEnvxvOES_t glTexEnvxvOES;
+ glTexParameterxOES_t glTexParameterxOES;
+ glTexParameterxvOES_t glTexParameterxvOES;
+ glTranslatexOES_t glTranslatexOES;
+ glIsRenderbufferOES_t glIsRenderbufferOES;
+ glBindRenderbufferOES_t glBindRenderbufferOES;
+ glDeleteRenderbuffersOES_t glDeleteRenderbuffersOES;
+ glGenRenderbuffersOES_t glGenRenderbuffersOES;
+ glRenderbufferStorageOES_t glRenderbufferStorageOES;
+ glGetRenderbufferParameterivOES_t glGetRenderbufferParameterivOES;
+ glIsFramebufferOES_t glIsFramebufferOES;
+ glBindFramebufferOES_t glBindFramebufferOES;
+ glDeleteFramebuffersOES_t glDeleteFramebuffersOES;
+ glGenFramebuffersOES_t glGenFramebuffersOES;
+ glCheckFramebufferStatusOES_t glCheckFramebufferStatusOES;
+ glFramebufferRenderbufferOES_t glFramebufferRenderbufferOES;
+ glFramebufferTexture2DOES_t glFramebufferTexture2DOES;
+ glGetFramebufferAttachmentParameterivOES_t glGetFramebufferAttachmentParameterivOES;
+ glGenerateMipmapOES_t glGenerateMipmapOES;
+ glMapBufferOES_t glMapBufferOES;
+ glUnmapBufferOES_t glUnmapBufferOES;
+ glGetBufferPointervOES_t glGetBufferPointervOES;
+ glCurrentPaletteMatrixOES_t glCurrentPaletteMatrixOES;
+ glLoadPaletteFromModelViewMatrixOES_t glLoadPaletteFromModelViewMatrixOES;
+ glMatrixIndexPointerOES_t glMatrixIndexPointerOES;
+ glWeightPointerOES_t glWeightPointerOES;
+ glQueryMatrixxOES_t glQueryMatrixxOES;
+ glDepthRangefOES_t glDepthRangefOES;
+ glFrustumfOES_t glFrustumfOES;
+ glOrthofOES_t glOrthofOES;
+ glClipPlanefOES_t glClipPlanefOES;
+ glGetClipPlanefOES_t glGetClipPlanefOES;
+ glClearDepthfOES_t glClearDepthfOES;
+ glTexGenfOES_t glTexGenfOES;
+ glTexGenfvOES_t glTexGenfvOES;
+ glTexGeniOES_t glTexGeniOES;
+ glTexGenivOES_t glTexGenivOES;
+ glTexGenxOES_t glTexGenxOES;
+ glTexGenxvOES_t glTexGenxvOES;
+ glGetTexGenfvOES_t glGetTexGenfvOES;
+ glGetTexGenivOES_t glGetTexGenivOES;
+ glGetTexGenxvOES_t glGetTexGenxvOES;
+ glBindVertexArrayOES_t glBindVertexArrayOES;
+ glDeleteVertexArraysOES_t glDeleteVertexArraysOES;
+ glGenVertexArraysOES_t glGenVertexArraysOES;
+ glIsVertexArrayOES_t glIsVertexArrayOES;
+ glDiscardFramebufferEXT_t glDiscardFramebufferEXT;
+ glMultiDrawArraysEXT_t glMultiDrawArraysEXT;
+ glMultiDrawElementsEXT_t glMultiDrawElementsEXT;
+ glClipPlanefIMG_t glClipPlanefIMG;
+ glClipPlanexIMG_t glClipPlanexIMG;
+ glRenderbufferStorageMultisampleIMG_t glRenderbufferStorageMultisampleIMG;
+ glFramebufferTexture2DMultisampleIMG_t glFramebufferTexture2DMultisampleIMG;
+ glDeleteFencesNV_t glDeleteFencesNV;
+ glGenFencesNV_t glGenFencesNV;
+ glIsFenceNV_t glIsFenceNV;
+ glTestFenceNV_t glTestFenceNV;
+ glGetFenceivNV_t glGetFenceivNV;
+ glFinishFenceNV_t glFinishFenceNV;
+ glSetFenceNV_t glSetFenceNV;
+ glGetDriverControlsQCOM_t glGetDriverControlsQCOM;
+ glGetDriverControlStringQCOM_t glGetDriverControlStringQCOM;
+ glEnableDriverControlQCOM_t glEnableDriverControlQCOM;
+ glDisableDriverControlQCOM_t glDisableDriverControlQCOM;
+ glExtGetTexturesQCOM_t glExtGetTexturesQCOM;
+ glExtGetBuffersQCOM_t glExtGetBuffersQCOM;
+ glExtGetRenderbuffersQCOM_t glExtGetRenderbuffersQCOM;
+ glExtGetFramebuffersQCOM_t glExtGetFramebuffersQCOM;
+ glExtGetTexLevelParameterivQCOM_t glExtGetTexLevelParameterivQCOM;
+ glExtTexObjectStateOverrideiQCOM_t glExtTexObjectStateOverrideiQCOM;
+ glExtGetTexSubImageQCOM_t glExtGetTexSubImageQCOM;
+ glExtGetBufferPointervQCOM_t glExtGetBufferPointervQCOM;
+ glExtGetShadersQCOM_t glExtGetShadersQCOM;
+ glExtGetProgramsQCOM_t glExtGetProgramsQCOM;
+ glExtIsProgramBinaryQCOM_t glExtIsProgramBinaryQCOM;
+ glExtGetProgramBinarySourceQCOM_t glExtGetProgramBinarySourceQCOM;
+ glStartTilingQCOM_t glStartTilingQCOM;
+ glEndTilingQCOM_t glEndTilingQCOM;
+ //Accessors
+ glAlphaFunc_t set_glAlphaFunc(glAlphaFunc_t f) { glAlphaFunc_t retval = glAlphaFunc; glAlphaFunc = f; return retval;}
+ glClearColor_t set_glClearColor(glClearColor_t f) { glClearColor_t retval = glClearColor; glClearColor = f; return retval;}
+ glClearDepthf_t set_glClearDepthf(glClearDepthf_t f) { glClearDepthf_t retval = glClearDepthf; glClearDepthf = f; return retval;}
+ glClipPlanef_t set_glClipPlanef(glClipPlanef_t f) { glClipPlanef_t retval = glClipPlanef; glClipPlanef = f; return retval;}
+ glColor4f_t set_glColor4f(glColor4f_t f) { glColor4f_t retval = glColor4f; glColor4f = f; return retval;}
+ glDepthRangef_t set_glDepthRangef(glDepthRangef_t f) { glDepthRangef_t retval = glDepthRangef; glDepthRangef = f; return retval;}
+ glFogf_t set_glFogf(glFogf_t f) { glFogf_t retval = glFogf; glFogf = f; return retval;}
+ glFogfv_t set_glFogfv(glFogfv_t f) { glFogfv_t retval = glFogfv; glFogfv = f; return retval;}
+ glFrustumf_t set_glFrustumf(glFrustumf_t f) { glFrustumf_t retval = glFrustumf; glFrustumf = f; return retval;}
+ glGetClipPlanef_t set_glGetClipPlanef(glGetClipPlanef_t f) { glGetClipPlanef_t retval = glGetClipPlanef; glGetClipPlanef = f; return retval;}
+ glGetFloatv_t set_glGetFloatv(glGetFloatv_t f) { glGetFloatv_t retval = glGetFloatv; glGetFloatv = f; return retval;}
+ glGetLightfv_t set_glGetLightfv(glGetLightfv_t f) { glGetLightfv_t retval = glGetLightfv; glGetLightfv = f; return retval;}
+ glGetMaterialfv_t set_glGetMaterialfv(glGetMaterialfv_t f) { glGetMaterialfv_t retval = glGetMaterialfv; glGetMaterialfv = f; return retval;}
+ glGetTexEnvfv_t set_glGetTexEnvfv(glGetTexEnvfv_t f) { glGetTexEnvfv_t retval = glGetTexEnvfv; glGetTexEnvfv = f; return retval;}
+ glGetTexParameterfv_t set_glGetTexParameterfv(glGetTexParameterfv_t f) { glGetTexParameterfv_t retval = glGetTexParameterfv; glGetTexParameterfv = f; return retval;}
+ glLightModelf_t set_glLightModelf(glLightModelf_t f) { glLightModelf_t retval = glLightModelf; glLightModelf = f; return retval;}
+ glLightModelfv_t set_glLightModelfv(glLightModelfv_t f) { glLightModelfv_t retval = glLightModelfv; glLightModelfv = f; return retval;}
+ glLightf_t set_glLightf(glLightf_t f) { glLightf_t retval = glLightf; glLightf = f; return retval;}
+ glLightfv_t set_glLightfv(glLightfv_t f) { glLightfv_t retval = glLightfv; glLightfv = f; return retval;}
+ glLineWidth_t set_glLineWidth(glLineWidth_t f) { glLineWidth_t retval = glLineWidth; glLineWidth = f; return retval;}
+ glLoadMatrixf_t set_glLoadMatrixf(glLoadMatrixf_t f) { glLoadMatrixf_t retval = glLoadMatrixf; glLoadMatrixf = f; return retval;}
+ glMaterialf_t set_glMaterialf(glMaterialf_t f) { glMaterialf_t retval = glMaterialf; glMaterialf = f; return retval;}
+ glMaterialfv_t set_glMaterialfv(glMaterialfv_t f) { glMaterialfv_t retval = glMaterialfv; glMaterialfv = f; return retval;}
+ glMultMatrixf_t set_glMultMatrixf(glMultMatrixf_t f) { glMultMatrixf_t retval = glMultMatrixf; glMultMatrixf = f; return retval;}
+ glMultiTexCoord4f_t set_glMultiTexCoord4f(glMultiTexCoord4f_t f) { glMultiTexCoord4f_t retval = glMultiTexCoord4f; glMultiTexCoord4f = f; return retval;}
+ glNormal3f_t set_glNormal3f(glNormal3f_t f) { glNormal3f_t retval = glNormal3f; glNormal3f = f; return retval;}
+ glOrthof_t set_glOrthof(glOrthof_t f) { glOrthof_t retval = glOrthof; glOrthof = f; return retval;}
+ glPointParameterf_t set_glPointParameterf(glPointParameterf_t f) { glPointParameterf_t retval = glPointParameterf; glPointParameterf = f; return retval;}
+ glPointParameterfv_t set_glPointParameterfv(glPointParameterfv_t f) { glPointParameterfv_t retval = glPointParameterfv; glPointParameterfv = f; return retval;}
+ glPointSize_t set_glPointSize(glPointSize_t f) { glPointSize_t retval = glPointSize; glPointSize = f; return retval;}
+ glPolygonOffset_t set_glPolygonOffset(glPolygonOffset_t f) { glPolygonOffset_t retval = glPolygonOffset; glPolygonOffset = f; return retval;}
+ glRotatef_t set_glRotatef(glRotatef_t f) { glRotatef_t retval = glRotatef; glRotatef = f; return retval;}
+ glScalef_t set_glScalef(glScalef_t f) { glScalef_t retval = glScalef; glScalef = f; return retval;}
+ glTexEnvf_t set_glTexEnvf(glTexEnvf_t f) { glTexEnvf_t retval = glTexEnvf; glTexEnvf = f; return retval;}
+ glTexEnvfv_t set_glTexEnvfv(glTexEnvfv_t f) { glTexEnvfv_t retval = glTexEnvfv; glTexEnvfv = f; return retval;}
+ glTexParameterf_t set_glTexParameterf(glTexParameterf_t f) { glTexParameterf_t retval = glTexParameterf; glTexParameterf = f; return retval;}
+ glTexParameterfv_t set_glTexParameterfv(glTexParameterfv_t f) { glTexParameterfv_t retval = glTexParameterfv; glTexParameterfv = f; return retval;}
+ glTranslatef_t set_glTranslatef(glTranslatef_t f) { glTranslatef_t retval = glTranslatef; glTranslatef = f; return retval;}
+ glActiveTexture_t set_glActiveTexture(glActiveTexture_t f) { glActiveTexture_t retval = glActiveTexture; glActiveTexture = f; return retval;}
+ glAlphaFuncx_t set_glAlphaFuncx(glAlphaFuncx_t f) { glAlphaFuncx_t retval = glAlphaFuncx; glAlphaFuncx = f; return retval;}
+ glBindBuffer_t set_glBindBuffer(glBindBuffer_t f) { glBindBuffer_t retval = glBindBuffer; glBindBuffer = f; return retval;}
+ glBindTexture_t set_glBindTexture(glBindTexture_t f) { glBindTexture_t retval = glBindTexture; glBindTexture = f; return retval;}
+ glBlendFunc_t set_glBlendFunc(glBlendFunc_t f) { glBlendFunc_t retval = glBlendFunc; glBlendFunc = f; return retval;}
+ glBufferData_t set_glBufferData(glBufferData_t f) { glBufferData_t retval = glBufferData; glBufferData = f; return retval;}
+ glBufferSubData_t set_glBufferSubData(glBufferSubData_t f) { glBufferSubData_t retval = glBufferSubData; glBufferSubData = f; return retval;}
+ glClear_t set_glClear(glClear_t f) { glClear_t retval = glClear; glClear = f; return retval;}
+ glClearColorx_t set_glClearColorx(glClearColorx_t f) { glClearColorx_t retval = glClearColorx; glClearColorx = f; return retval;}
+ glClearDepthx_t set_glClearDepthx(glClearDepthx_t f) { glClearDepthx_t retval = glClearDepthx; glClearDepthx = f; return retval;}
+ glClearStencil_t set_glClearStencil(glClearStencil_t f) { glClearStencil_t retval = glClearStencil; glClearStencil = f; return retval;}
+ glClientActiveTexture_t set_glClientActiveTexture(glClientActiveTexture_t f) { glClientActiveTexture_t retval = glClientActiveTexture; glClientActiveTexture = f; return retval;}
+ glClipPlanex_t set_glClipPlanex(glClipPlanex_t f) { glClipPlanex_t retval = glClipPlanex; glClipPlanex = f; return retval;}
+ glColor4ub_t set_glColor4ub(glColor4ub_t f) { glColor4ub_t retval = glColor4ub; glColor4ub = f; return retval;}
+ glColor4x_t set_glColor4x(glColor4x_t f) { glColor4x_t retval = glColor4x; glColor4x = f; return retval;}
+ glColorMask_t set_glColorMask(glColorMask_t f) { glColorMask_t retval = glColorMask; glColorMask = f; return retval;}
+ glColorPointer_t set_glColorPointer(glColorPointer_t f) { glColorPointer_t retval = glColorPointer; glColorPointer = f; return retval;}
+ glCompressedTexImage2D_t set_glCompressedTexImage2D(glCompressedTexImage2D_t f) { glCompressedTexImage2D_t retval = glCompressedTexImage2D; glCompressedTexImage2D = f; return retval;}
+ glCompressedTexSubImage2D_t set_glCompressedTexSubImage2D(glCompressedTexSubImage2D_t f) { glCompressedTexSubImage2D_t retval = glCompressedTexSubImage2D; glCompressedTexSubImage2D = f; return retval;}
+ glCopyTexImage2D_t set_glCopyTexImage2D(glCopyTexImage2D_t f) { glCopyTexImage2D_t retval = glCopyTexImage2D; glCopyTexImage2D = f; return retval;}
+ glCopyTexSubImage2D_t set_glCopyTexSubImage2D(glCopyTexSubImage2D_t f) { glCopyTexSubImage2D_t retval = glCopyTexSubImage2D; glCopyTexSubImage2D = f; return retval;}
+ glCullFace_t set_glCullFace(glCullFace_t f) { glCullFace_t retval = glCullFace; glCullFace = f; return retval;}
+ glDeleteBuffers_t set_glDeleteBuffers(glDeleteBuffers_t f) { glDeleteBuffers_t retval = glDeleteBuffers; glDeleteBuffers = f; return retval;}
+ glDeleteTextures_t set_glDeleteTextures(glDeleteTextures_t f) { glDeleteTextures_t retval = glDeleteTextures; glDeleteTextures = f; return retval;}
+ glDepthFunc_t set_glDepthFunc(glDepthFunc_t f) { glDepthFunc_t retval = glDepthFunc; glDepthFunc = f; return retval;}
+ glDepthMask_t set_glDepthMask(glDepthMask_t f) { glDepthMask_t retval = glDepthMask; glDepthMask = f; return retval;}
+ glDepthRangex_t set_glDepthRangex(glDepthRangex_t f) { glDepthRangex_t retval = glDepthRangex; glDepthRangex = f; return retval;}
+ glDisable_t set_glDisable(glDisable_t f) { glDisable_t retval = glDisable; glDisable = f; return retval;}
+ glDisableClientState_t set_glDisableClientState(glDisableClientState_t f) { glDisableClientState_t retval = glDisableClientState; glDisableClientState = f; return retval;}
+ glDrawArrays_t set_glDrawArrays(glDrawArrays_t f) { glDrawArrays_t retval = glDrawArrays; glDrawArrays = f; return retval;}
+ glDrawElements_t set_glDrawElements(glDrawElements_t f) { glDrawElements_t retval = glDrawElements; glDrawElements = f; return retval;}
+ glEnable_t set_glEnable(glEnable_t f) { glEnable_t retval = glEnable; glEnable = f; return retval;}
+ glEnableClientState_t set_glEnableClientState(glEnableClientState_t f) { glEnableClientState_t retval = glEnableClientState; glEnableClientState = f; return retval;}
+ glFinish_t set_glFinish(glFinish_t f) { glFinish_t retval = glFinish; glFinish = f; return retval;}
+ glFlush_t set_glFlush(glFlush_t f) { glFlush_t retval = glFlush; glFlush = f; return retval;}
+ glFogx_t set_glFogx(glFogx_t f) { glFogx_t retval = glFogx; glFogx = f; return retval;}
+ glFogxv_t set_glFogxv(glFogxv_t f) { glFogxv_t retval = glFogxv; glFogxv = f; return retval;}
+ glFrontFace_t set_glFrontFace(glFrontFace_t f) { glFrontFace_t retval = glFrontFace; glFrontFace = f; return retval;}
+ glFrustumx_t set_glFrustumx(glFrustumx_t f) { glFrustumx_t retval = glFrustumx; glFrustumx = f; return retval;}
+ glGetBooleanv_t set_glGetBooleanv(glGetBooleanv_t f) { glGetBooleanv_t retval = glGetBooleanv; glGetBooleanv = f; return retval;}
+ glGetBufferParameteriv_t set_glGetBufferParameteriv(glGetBufferParameteriv_t f) { glGetBufferParameteriv_t retval = glGetBufferParameteriv; glGetBufferParameteriv = f; return retval;}
+ glGetClipPlanex_t set_glGetClipPlanex(glGetClipPlanex_t f) { glGetClipPlanex_t retval = glGetClipPlanex; glGetClipPlanex = f; return retval;}
+ glGenBuffers_t set_glGenBuffers(glGenBuffers_t f) { glGenBuffers_t retval = glGenBuffers; glGenBuffers = f; return retval;}
+ glGenTextures_t set_glGenTextures(glGenTextures_t f) { glGenTextures_t retval = glGenTextures; glGenTextures = f; return retval;}
+ glGetError_t set_glGetError(glGetError_t f) { glGetError_t retval = glGetError; glGetError = f; return retval;}
+ glGetFixedv_t set_glGetFixedv(glGetFixedv_t f) { glGetFixedv_t retval = glGetFixedv; glGetFixedv = f; return retval;}
+ glGetIntegerv_t set_glGetIntegerv(glGetIntegerv_t f) { glGetIntegerv_t retval = glGetIntegerv; glGetIntegerv = f; return retval;}
+ glGetLightxv_t set_glGetLightxv(glGetLightxv_t f) { glGetLightxv_t retval = glGetLightxv; glGetLightxv = f; return retval;}
+ glGetMaterialxv_t set_glGetMaterialxv(glGetMaterialxv_t f) { glGetMaterialxv_t retval = glGetMaterialxv; glGetMaterialxv = f; return retval;}
+ glGetPointerv_t set_glGetPointerv(glGetPointerv_t f) { glGetPointerv_t retval = glGetPointerv; glGetPointerv = f; return retval;}
+ glGetString_t set_glGetString(glGetString_t f) { glGetString_t retval = glGetString; glGetString = f; return retval;}
+ glGetTexEnviv_t set_glGetTexEnviv(glGetTexEnviv_t f) { glGetTexEnviv_t retval = glGetTexEnviv; glGetTexEnviv = f; return retval;}
+ glGetTexEnvxv_t set_glGetTexEnvxv(glGetTexEnvxv_t f) { glGetTexEnvxv_t retval = glGetTexEnvxv; glGetTexEnvxv = f; return retval;}
+ glGetTexParameteriv_t set_glGetTexParameteriv(glGetTexParameteriv_t f) { glGetTexParameteriv_t retval = glGetTexParameteriv; glGetTexParameteriv = f; return retval;}
+ glGetTexParameterxv_t set_glGetTexParameterxv(glGetTexParameterxv_t f) { glGetTexParameterxv_t retval = glGetTexParameterxv; glGetTexParameterxv = f; return retval;}
+ glHint_t set_glHint(glHint_t f) { glHint_t retval = glHint; glHint = f; return retval;}
+ glIsBuffer_t set_glIsBuffer(glIsBuffer_t f) { glIsBuffer_t retval = glIsBuffer; glIsBuffer = f; return retval;}
+ glIsEnabled_t set_glIsEnabled(glIsEnabled_t f) { glIsEnabled_t retval = glIsEnabled; glIsEnabled = f; return retval;}
+ glIsTexture_t set_glIsTexture(glIsTexture_t f) { glIsTexture_t retval = glIsTexture; glIsTexture = f; return retval;}
+ glLightModelx_t set_glLightModelx(glLightModelx_t f) { glLightModelx_t retval = glLightModelx; glLightModelx = f; return retval;}
+ glLightModelxv_t set_glLightModelxv(glLightModelxv_t f) { glLightModelxv_t retval = glLightModelxv; glLightModelxv = f; return retval;}
+ glLightx_t set_glLightx(glLightx_t f) { glLightx_t retval = glLightx; glLightx = f; return retval;}
+ glLightxv_t set_glLightxv(glLightxv_t f) { glLightxv_t retval = glLightxv; glLightxv = f; return retval;}
+ glLineWidthx_t set_glLineWidthx(glLineWidthx_t f) { glLineWidthx_t retval = glLineWidthx; glLineWidthx = f; return retval;}
+ glLoadIdentity_t set_glLoadIdentity(glLoadIdentity_t f) { glLoadIdentity_t retval = glLoadIdentity; glLoadIdentity = f; return retval;}
+ glLoadMatrixx_t set_glLoadMatrixx(glLoadMatrixx_t f) { glLoadMatrixx_t retval = glLoadMatrixx; glLoadMatrixx = f; return retval;}
+ glLogicOp_t set_glLogicOp(glLogicOp_t f) { glLogicOp_t retval = glLogicOp; glLogicOp = f; return retval;}
+ glMaterialx_t set_glMaterialx(glMaterialx_t f) { glMaterialx_t retval = glMaterialx; glMaterialx = f; return retval;}
+ glMaterialxv_t set_glMaterialxv(glMaterialxv_t f) { glMaterialxv_t retval = glMaterialxv; glMaterialxv = f; return retval;}
+ glMatrixMode_t set_glMatrixMode(glMatrixMode_t f) { glMatrixMode_t retval = glMatrixMode; glMatrixMode = f; return retval;}
+ glMultMatrixx_t set_glMultMatrixx(glMultMatrixx_t f) { glMultMatrixx_t retval = glMultMatrixx; glMultMatrixx = f; return retval;}
+ glMultiTexCoord4x_t set_glMultiTexCoord4x(glMultiTexCoord4x_t f) { glMultiTexCoord4x_t retval = glMultiTexCoord4x; glMultiTexCoord4x = f; return retval;}
+ glNormal3x_t set_glNormal3x(glNormal3x_t f) { glNormal3x_t retval = glNormal3x; glNormal3x = f; return retval;}
+ glNormalPointer_t set_glNormalPointer(glNormalPointer_t f) { glNormalPointer_t retval = glNormalPointer; glNormalPointer = f; return retval;}
+ glOrthox_t set_glOrthox(glOrthox_t f) { glOrthox_t retval = glOrthox; glOrthox = f; return retval;}
+ glPixelStorei_t set_glPixelStorei(glPixelStorei_t f) { glPixelStorei_t retval = glPixelStorei; glPixelStorei = f; return retval;}
+ glPointParameterx_t set_glPointParameterx(glPointParameterx_t f) { glPointParameterx_t retval = glPointParameterx; glPointParameterx = f; return retval;}
+ glPointParameterxv_t set_glPointParameterxv(glPointParameterxv_t f) { glPointParameterxv_t retval = glPointParameterxv; glPointParameterxv = f; return retval;}
+ glPointSizex_t set_glPointSizex(glPointSizex_t f) { glPointSizex_t retval = glPointSizex; glPointSizex = f; return retval;}
+ glPolygonOffsetx_t set_glPolygonOffsetx(glPolygonOffsetx_t f) { glPolygonOffsetx_t retval = glPolygonOffsetx; glPolygonOffsetx = f; return retval;}
+ glPopMatrix_t set_glPopMatrix(glPopMatrix_t f) { glPopMatrix_t retval = glPopMatrix; glPopMatrix = f; return retval;}
+ glPushMatrix_t set_glPushMatrix(glPushMatrix_t f) { glPushMatrix_t retval = glPushMatrix; glPushMatrix = f; return retval;}
+ glReadPixels_t set_glReadPixels(glReadPixels_t f) { glReadPixels_t retval = glReadPixels; glReadPixels = f; return retval;}
+ glRotatex_t set_glRotatex(glRotatex_t f) { glRotatex_t retval = glRotatex; glRotatex = f; return retval;}
+ glSampleCoverage_t set_glSampleCoverage(glSampleCoverage_t f) { glSampleCoverage_t retval = glSampleCoverage; glSampleCoverage = f; return retval;}
+ glSampleCoveragex_t set_glSampleCoveragex(glSampleCoveragex_t f) { glSampleCoveragex_t retval = glSampleCoveragex; glSampleCoveragex = f; return retval;}
+ glScalex_t set_glScalex(glScalex_t f) { glScalex_t retval = glScalex; glScalex = f; return retval;}
+ glScissor_t set_glScissor(glScissor_t f) { glScissor_t retval = glScissor; glScissor = f; return retval;}
+ glShadeModel_t set_glShadeModel(glShadeModel_t f) { glShadeModel_t retval = glShadeModel; glShadeModel = f; return retval;}
+ glStencilFunc_t set_glStencilFunc(glStencilFunc_t f) { glStencilFunc_t retval = glStencilFunc; glStencilFunc = f; return retval;}
+ glStencilMask_t set_glStencilMask(glStencilMask_t f) { glStencilMask_t retval = glStencilMask; glStencilMask = f; return retval;}
+ glStencilOp_t set_glStencilOp(glStencilOp_t f) { glStencilOp_t retval = glStencilOp; glStencilOp = f; return retval;}
+ glTexCoordPointer_t set_glTexCoordPointer(glTexCoordPointer_t f) { glTexCoordPointer_t retval = glTexCoordPointer; glTexCoordPointer = f; return retval;}
+ glTexEnvi_t set_glTexEnvi(glTexEnvi_t f) { glTexEnvi_t retval = glTexEnvi; glTexEnvi = f; return retval;}
+ glTexEnvx_t set_glTexEnvx(glTexEnvx_t f) { glTexEnvx_t retval = glTexEnvx; glTexEnvx = f; return retval;}
+ glTexEnviv_t set_glTexEnviv(glTexEnviv_t f) { glTexEnviv_t retval = glTexEnviv; glTexEnviv = f; return retval;}
+ glTexEnvxv_t set_glTexEnvxv(glTexEnvxv_t f) { glTexEnvxv_t retval = glTexEnvxv; glTexEnvxv = f; return retval;}
+ glTexImage2D_t set_glTexImage2D(glTexImage2D_t f) { glTexImage2D_t retval = glTexImage2D; glTexImage2D = f; return retval;}
+ glTexParameteri_t set_glTexParameteri(glTexParameteri_t f) { glTexParameteri_t retval = glTexParameteri; glTexParameteri = f; return retval;}
+ glTexParameterx_t set_glTexParameterx(glTexParameterx_t f) { glTexParameterx_t retval = glTexParameterx; glTexParameterx = f; return retval;}
+ glTexParameteriv_t set_glTexParameteriv(glTexParameteriv_t f) { glTexParameteriv_t retval = glTexParameteriv; glTexParameteriv = f; return retval;}
+ glTexParameterxv_t set_glTexParameterxv(glTexParameterxv_t f) { glTexParameterxv_t retval = glTexParameterxv; glTexParameterxv = f; return retval;}
+ glTexSubImage2D_t set_glTexSubImage2D(glTexSubImage2D_t f) { glTexSubImage2D_t retval = glTexSubImage2D; glTexSubImage2D = f; return retval;}
+ glTranslatex_t set_glTranslatex(glTranslatex_t f) { glTranslatex_t retval = glTranslatex; glTranslatex = f; return retval;}
+ glVertexPointer_t set_glVertexPointer(glVertexPointer_t f) { glVertexPointer_t retval = glVertexPointer; glVertexPointer = f; return retval;}
+ glViewport_t set_glViewport(glViewport_t f) { glViewport_t retval = glViewport; glViewport = f; return retval;}
+ glPointSizePointerOES_t set_glPointSizePointerOES(glPointSizePointerOES_t f) { glPointSizePointerOES_t retval = glPointSizePointerOES; glPointSizePointerOES = f; return retval;}
+ glBlendEquationSeparateOES_t set_glBlendEquationSeparateOES(glBlendEquationSeparateOES_t f) { glBlendEquationSeparateOES_t retval = glBlendEquationSeparateOES; glBlendEquationSeparateOES = f; return retval;}
+ glBlendFuncSeparateOES_t set_glBlendFuncSeparateOES(glBlendFuncSeparateOES_t f) { glBlendFuncSeparateOES_t retval = glBlendFuncSeparateOES; glBlendFuncSeparateOES = f; return retval;}
+ glBlendEquationOES_t set_glBlendEquationOES(glBlendEquationOES_t f) { glBlendEquationOES_t retval = glBlendEquationOES; glBlendEquationOES = f; return retval;}
+ glDrawTexsOES_t set_glDrawTexsOES(glDrawTexsOES_t f) { glDrawTexsOES_t retval = glDrawTexsOES; glDrawTexsOES = f; return retval;}
+ glDrawTexiOES_t set_glDrawTexiOES(glDrawTexiOES_t f) { glDrawTexiOES_t retval = glDrawTexiOES; glDrawTexiOES = f; return retval;}
+ glDrawTexxOES_t set_glDrawTexxOES(glDrawTexxOES_t f) { glDrawTexxOES_t retval = glDrawTexxOES; glDrawTexxOES = f; return retval;}
+ glDrawTexsvOES_t set_glDrawTexsvOES(glDrawTexsvOES_t f) { glDrawTexsvOES_t retval = glDrawTexsvOES; glDrawTexsvOES = f; return retval;}
+ glDrawTexivOES_t set_glDrawTexivOES(glDrawTexivOES_t f) { glDrawTexivOES_t retval = glDrawTexivOES; glDrawTexivOES = f; return retval;}
+ glDrawTexxvOES_t set_glDrawTexxvOES(glDrawTexxvOES_t f) { glDrawTexxvOES_t retval = glDrawTexxvOES; glDrawTexxvOES = f; return retval;}
+ glDrawTexfOES_t set_glDrawTexfOES(glDrawTexfOES_t f) { glDrawTexfOES_t retval = glDrawTexfOES; glDrawTexfOES = f; return retval;}
+ glDrawTexfvOES_t set_glDrawTexfvOES(glDrawTexfvOES_t f) { glDrawTexfvOES_t retval = glDrawTexfvOES; glDrawTexfvOES = f; return retval;}
+ glEGLImageTargetTexture2DOES_t set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES_t f) { glEGLImageTargetTexture2DOES_t retval = glEGLImageTargetTexture2DOES; glEGLImageTargetTexture2DOES = f; return retval;}
+ glEGLImageTargetRenderbufferStorageOES_t set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES_t f) { glEGLImageTargetRenderbufferStorageOES_t retval = glEGLImageTargetRenderbufferStorageOES; glEGLImageTargetRenderbufferStorageOES = f; return retval;}
+ glAlphaFuncxOES_t set_glAlphaFuncxOES(glAlphaFuncxOES_t f) { glAlphaFuncxOES_t retval = glAlphaFuncxOES; glAlphaFuncxOES = f; return retval;}
+ glClearColorxOES_t set_glClearColorxOES(glClearColorxOES_t f) { glClearColorxOES_t retval = glClearColorxOES; glClearColorxOES = f; return retval;}
+ glClearDepthxOES_t set_glClearDepthxOES(glClearDepthxOES_t f) { glClearDepthxOES_t retval = glClearDepthxOES; glClearDepthxOES = f; return retval;}
+ glClipPlanexOES_t set_glClipPlanexOES(glClipPlanexOES_t f) { glClipPlanexOES_t retval = glClipPlanexOES; glClipPlanexOES = f; return retval;}
+ glColor4xOES_t set_glColor4xOES(glColor4xOES_t f) { glColor4xOES_t retval = glColor4xOES; glColor4xOES = f; return retval;}
+ glDepthRangexOES_t set_glDepthRangexOES(glDepthRangexOES_t f) { glDepthRangexOES_t retval = glDepthRangexOES; glDepthRangexOES = f; return retval;}
+ glFogxOES_t set_glFogxOES(glFogxOES_t f) { glFogxOES_t retval = glFogxOES; glFogxOES = f; return retval;}
+ glFogxvOES_t set_glFogxvOES(glFogxvOES_t f) { glFogxvOES_t retval = glFogxvOES; glFogxvOES = f; return retval;}
+ glFrustumxOES_t set_glFrustumxOES(glFrustumxOES_t f) { glFrustumxOES_t retval = glFrustumxOES; glFrustumxOES = f; return retval;}
+ glGetClipPlanexOES_t set_glGetClipPlanexOES(glGetClipPlanexOES_t f) { glGetClipPlanexOES_t retval = glGetClipPlanexOES; glGetClipPlanexOES = f; return retval;}
+ glGetFixedvOES_t set_glGetFixedvOES(glGetFixedvOES_t f) { glGetFixedvOES_t retval = glGetFixedvOES; glGetFixedvOES = f; return retval;}
+ glGetLightxvOES_t set_glGetLightxvOES(glGetLightxvOES_t f) { glGetLightxvOES_t retval = glGetLightxvOES; glGetLightxvOES = f; return retval;}
+ glGetMaterialxvOES_t set_glGetMaterialxvOES(glGetMaterialxvOES_t f) { glGetMaterialxvOES_t retval = glGetMaterialxvOES; glGetMaterialxvOES = f; return retval;}
+ glGetTexEnvxvOES_t set_glGetTexEnvxvOES(glGetTexEnvxvOES_t f) { glGetTexEnvxvOES_t retval = glGetTexEnvxvOES; glGetTexEnvxvOES = f; return retval;}
+ glGetTexParameterxvOES_t set_glGetTexParameterxvOES(glGetTexParameterxvOES_t f) { glGetTexParameterxvOES_t retval = glGetTexParameterxvOES; glGetTexParameterxvOES = f; return retval;}
+ glLightModelxOES_t set_glLightModelxOES(glLightModelxOES_t f) { glLightModelxOES_t retval = glLightModelxOES; glLightModelxOES = f; return retval;}
+ glLightModelxvOES_t set_glLightModelxvOES(glLightModelxvOES_t f) { glLightModelxvOES_t retval = glLightModelxvOES; glLightModelxvOES = f; return retval;}
+ glLightxOES_t set_glLightxOES(glLightxOES_t f) { glLightxOES_t retval = glLightxOES; glLightxOES = f; return retval;}
+ glLightxvOES_t set_glLightxvOES(glLightxvOES_t f) { glLightxvOES_t retval = glLightxvOES; glLightxvOES = f; return retval;}
+ glLineWidthxOES_t set_glLineWidthxOES(glLineWidthxOES_t f) { glLineWidthxOES_t retval = glLineWidthxOES; glLineWidthxOES = f; return retval;}
+ glLoadMatrixxOES_t set_glLoadMatrixxOES(glLoadMatrixxOES_t f) { glLoadMatrixxOES_t retval = glLoadMatrixxOES; glLoadMatrixxOES = f; return retval;}
+ glMaterialxOES_t set_glMaterialxOES(glMaterialxOES_t f) { glMaterialxOES_t retval = glMaterialxOES; glMaterialxOES = f; return retval;}
+ glMaterialxvOES_t set_glMaterialxvOES(glMaterialxvOES_t f) { glMaterialxvOES_t retval = glMaterialxvOES; glMaterialxvOES = f; return retval;}
+ glMultMatrixxOES_t set_glMultMatrixxOES(glMultMatrixxOES_t f) { glMultMatrixxOES_t retval = glMultMatrixxOES; glMultMatrixxOES = f; return retval;}
+ glMultiTexCoord4xOES_t set_glMultiTexCoord4xOES(glMultiTexCoord4xOES_t f) { glMultiTexCoord4xOES_t retval = glMultiTexCoord4xOES; glMultiTexCoord4xOES = f; return retval;}
+ glNormal3xOES_t set_glNormal3xOES(glNormal3xOES_t f) { glNormal3xOES_t retval = glNormal3xOES; glNormal3xOES = f; return retval;}
+ glOrthoxOES_t set_glOrthoxOES(glOrthoxOES_t f) { glOrthoxOES_t retval = glOrthoxOES; glOrthoxOES = f; return retval;}
+ glPointParameterxOES_t set_glPointParameterxOES(glPointParameterxOES_t f) { glPointParameterxOES_t retval = glPointParameterxOES; glPointParameterxOES = f; return retval;}
+ glPointParameterxvOES_t set_glPointParameterxvOES(glPointParameterxvOES_t f) { glPointParameterxvOES_t retval = glPointParameterxvOES; glPointParameterxvOES = f; return retval;}
+ glPointSizexOES_t set_glPointSizexOES(glPointSizexOES_t f) { glPointSizexOES_t retval = glPointSizexOES; glPointSizexOES = f; return retval;}
+ glPolygonOffsetxOES_t set_glPolygonOffsetxOES(glPolygonOffsetxOES_t f) { glPolygonOffsetxOES_t retval = glPolygonOffsetxOES; glPolygonOffsetxOES = f; return retval;}
+ glRotatexOES_t set_glRotatexOES(glRotatexOES_t f) { glRotatexOES_t retval = glRotatexOES; glRotatexOES = f; return retval;}
+ glSampleCoveragexOES_t set_glSampleCoveragexOES(glSampleCoveragexOES_t f) { glSampleCoveragexOES_t retval = glSampleCoveragexOES; glSampleCoveragexOES = f; return retval;}
+ glScalexOES_t set_glScalexOES(glScalexOES_t f) { glScalexOES_t retval = glScalexOES; glScalexOES = f; return retval;}
+ glTexEnvxOES_t set_glTexEnvxOES(glTexEnvxOES_t f) { glTexEnvxOES_t retval = glTexEnvxOES; glTexEnvxOES = f; return retval;}
+ glTexEnvxvOES_t set_glTexEnvxvOES(glTexEnvxvOES_t f) { glTexEnvxvOES_t retval = glTexEnvxvOES; glTexEnvxvOES = f; return retval;}
+ glTexParameterxOES_t set_glTexParameterxOES(glTexParameterxOES_t f) { glTexParameterxOES_t retval = glTexParameterxOES; glTexParameterxOES = f; return retval;}
+ glTexParameterxvOES_t set_glTexParameterxvOES(glTexParameterxvOES_t f) { glTexParameterxvOES_t retval = glTexParameterxvOES; glTexParameterxvOES = f; return retval;}
+ glTranslatexOES_t set_glTranslatexOES(glTranslatexOES_t f) { glTranslatexOES_t retval = glTranslatexOES; glTranslatexOES = f; return retval;}
+ glIsRenderbufferOES_t set_glIsRenderbufferOES(glIsRenderbufferOES_t f) { glIsRenderbufferOES_t retval = glIsRenderbufferOES; glIsRenderbufferOES = f; return retval;}
+ glBindRenderbufferOES_t set_glBindRenderbufferOES(glBindRenderbufferOES_t f) { glBindRenderbufferOES_t retval = glBindRenderbufferOES; glBindRenderbufferOES = f; return retval;}
+ glDeleteRenderbuffersOES_t set_glDeleteRenderbuffersOES(glDeleteRenderbuffersOES_t f) { glDeleteRenderbuffersOES_t retval = glDeleteRenderbuffersOES; glDeleteRenderbuffersOES = f; return retval;}
+ glGenRenderbuffersOES_t set_glGenRenderbuffersOES(glGenRenderbuffersOES_t f) { glGenRenderbuffersOES_t retval = glGenRenderbuffersOES; glGenRenderbuffersOES = f; return retval;}
+ glRenderbufferStorageOES_t set_glRenderbufferStorageOES(glRenderbufferStorageOES_t f) { glRenderbufferStorageOES_t retval = glRenderbufferStorageOES; glRenderbufferStorageOES = f; return retval;}
+ glGetRenderbufferParameterivOES_t set_glGetRenderbufferParameterivOES(glGetRenderbufferParameterivOES_t f) { glGetRenderbufferParameterivOES_t retval = glGetRenderbufferParameterivOES; glGetRenderbufferParameterivOES = f; return retval;}
+ glIsFramebufferOES_t set_glIsFramebufferOES(glIsFramebufferOES_t f) { glIsFramebufferOES_t retval = glIsFramebufferOES; glIsFramebufferOES = f; return retval;}
+ glBindFramebufferOES_t set_glBindFramebufferOES(glBindFramebufferOES_t f) { glBindFramebufferOES_t retval = glBindFramebufferOES; glBindFramebufferOES = f; return retval;}
+ glDeleteFramebuffersOES_t set_glDeleteFramebuffersOES(glDeleteFramebuffersOES_t f) { glDeleteFramebuffersOES_t retval = glDeleteFramebuffersOES; glDeleteFramebuffersOES = f; return retval;}
+ glGenFramebuffersOES_t set_glGenFramebuffersOES(glGenFramebuffersOES_t f) { glGenFramebuffersOES_t retval = glGenFramebuffersOES; glGenFramebuffersOES = f; return retval;}
+ glCheckFramebufferStatusOES_t set_glCheckFramebufferStatusOES(glCheckFramebufferStatusOES_t f) { glCheckFramebufferStatusOES_t retval = glCheckFramebufferStatusOES; glCheckFramebufferStatusOES = f; return retval;}
+ glFramebufferRenderbufferOES_t set_glFramebufferRenderbufferOES(glFramebufferRenderbufferOES_t f) { glFramebufferRenderbufferOES_t retval = glFramebufferRenderbufferOES; glFramebufferRenderbufferOES = f; return retval;}
+ glFramebufferTexture2DOES_t set_glFramebufferTexture2DOES(glFramebufferTexture2DOES_t f) { glFramebufferTexture2DOES_t retval = glFramebufferTexture2DOES; glFramebufferTexture2DOES = f; return retval;}
+ glGetFramebufferAttachmentParameterivOES_t set_glGetFramebufferAttachmentParameterivOES(glGetFramebufferAttachmentParameterivOES_t f) { glGetFramebufferAttachmentParameterivOES_t retval = glGetFramebufferAttachmentParameterivOES; glGetFramebufferAttachmentParameterivOES = f; return retval;}
+ glGenerateMipmapOES_t set_glGenerateMipmapOES(glGenerateMipmapOES_t f) { glGenerateMipmapOES_t retval = glGenerateMipmapOES; glGenerateMipmapOES = f; return retval;}
+ glMapBufferOES_t set_glMapBufferOES(glMapBufferOES_t f) { glMapBufferOES_t retval = glMapBufferOES; glMapBufferOES = f; return retval;}
+ glUnmapBufferOES_t set_glUnmapBufferOES(glUnmapBufferOES_t f) { glUnmapBufferOES_t retval = glUnmapBufferOES; glUnmapBufferOES = f; return retval;}
+ glGetBufferPointervOES_t set_glGetBufferPointervOES(glGetBufferPointervOES_t f) { glGetBufferPointervOES_t retval = glGetBufferPointervOES; glGetBufferPointervOES = f; return retval;}
+ glCurrentPaletteMatrixOES_t set_glCurrentPaletteMatrixOES(glCurrentPaletteMatrixOES_t f) { glCurrentPaletteMatrixOES_t retval = glCurrentPaletteMatrixOES; glCurrentPaletteMatrixOES = f; return retval;}
+ glLoadPaletteFromModelViewMatrixOES_t set_glLoadPaletteFromModelViewMatrixOES(glLoadPaletteFromModelViewMatrixOES_t f) { glLoadPaletteFromModelViewMatrixOES_t retval = glLoadPaletteFromModelViewMatrixOES; glLoadPaletteFromModelViewMatrixOES = f; return retval;}
+ glMatrixIndexPointerOES_t set_glMatrixIndexPointerOES(glMatrixIndexPointerOES_t f) { glMatrixIndexPointerOES_t retval = glMatrixIndexPointerOES; glMatrixIndexPointerOES = f; return retval;}
+ glWeightPointerOES_t set_glWeightPointerOES(glWeightPointerOES_t f) { glWeightPointerOES_t retval = glWeightPointerOES; glWeightPointerOES = f; return retval;}
+ glQueryMatrixxOES_t set_glQueryMatrixxOES(glQueryMatrixxOES_t f) { glQueryMatrixxOES_t retval = glQueryMatrixxOES; glQueryMatrixxOES = f; return retval;}
+ glDepthRangefOES_t set_glDepthRangefOES(glDepthRangefOES_t f) { glDepthRangefOES_t retval = glDepthRangefOES; glDepthRangefOES = f; return retval;}
+ glFrustumfOES_t set_glFrustumfOES(glFrustumfOES_t f) { glFrustumfOES_t retval = glFrustumfOES; glFrustumfOES = f; return retval;}
+ glOrthofOES_t set_glOrthofOES(glOrthofOES_t f) { glOrthofOES_t retval = glOrthofOES; glOrthofOES = f; return retval;}
+ glClipPlanefOES_t set_glClipPlanefOES(glClipPlanefOES_t f) { glClipPlanefOES_t retval = glClipPlanefOES; glClipPlanefOES = f; return retval;}
+ glGetClipPlanefOES_t set_glGetClipPlanefOES(glGetClipPlanefOES_t f) { glGetClipPlanefOES_t retval = glGetClipPlanefOES; glGetClipPlanefOES = f; return retval;}
+ glClearDepthfOES_t set_glClearDepthfOES(glClearDepthfOES_t f) { glClearDepthfOES_t retval = glClearDepthfOES; glClearDepthfOES = f; return retval;}
+ glTexGenfOES_t set_glTexGenfOES(glTexGenfOES_t f) { glTexGenfOES_t retval = glTexGenfOES; glTexGenfOES = f; return retval;}
+ glTexGenfvOES_t set_glTexGenfvOES(glTexGenfvOES_t f) { glTexGenfvOES_t retval = glTexGenfvOES; glTexGenfvOES = f; return retval;}
+ glTexGeniOES_t set_glTexGeniOES(glTexGeniOES_t f) { glTexGeniOES_t retval = glTexGeniOES; glTexGeniOES = f; return retval;}
+ glTexGenivOES_t set_glTexGenivOES(glTexGenivOES_t f) { glTexGenivOES_t retval = glTexGenivOES; glTexGenivOES = f; return retval;}
+ glTexGenxOES_t set_glTexGenxOES(glTexGenxOES_t f) { glTexGenxOES_t retval = glTexGenxOES; glTexGenxOES = f; return retval;}
+ glTexGenxvOES_t set_glTexGenxvOES(glTexGenxvOES_t f) { glTexGenxvOES_t retval = glTexGenxvOES; glTexGenxvOES = f; return retval;}
+ glGetTexGenfvOES_t set_glGetTexGenfvOES(glGetTexGenfvOES_t f) { glGetTexGenfvOES_t retval = glGetTexGenfvOES; glGetTexGenfvOES = f; return retval;}
+ glGetTexGenivOES_t set_glGetTexGenivOES(glGetTexGenivOES_t f) { glGetTexGenivOES_t retval = glGetTexGenivOES; glGetTexGenivOES = f; return retval;}
+ glGetTexGenxvOES_t set_glGetTexGenxvOES(glGetTexGenxvOES_t f) { glGetTexGenxvOES_t retval = glGetTexGenxvOES; glGetTexGenxvOES = f; return retval;}
+ glBindVertexArrayOES_t set_glBindVertexArrayOES(glBindVertexArrayOES_t f) { glBindVertexArrayOES_t retval = glBindVertexArrayOES; glBindVertexArrayOES = f; return retval;}
+ glDeleteVertexArraysOES_t set_glDeleteVertexArraysOES(glDeleteVertexArraysOES_t f) { glDeleteVertexArraysOES_t retval = glDeleteVertexArraysOES; glDeleteVertexArraysOES = f; return retval;}
+ glGenVertexArraysOES_t set_glGenVertexArraysOES(glGenVertexArraysOES_t f) { glGenVertexArraysOES_t retval = glGenVertexArraysOES; glGenVertexArraysOES = f; return retval;}
+ glIsVertexArrayOES_t set_glIsVertexArrayOES(glIsVertexArrayOES_t f) { glIsVertexArrayOES_t retval = glIsVertexArrayOES; glIsVertexArrayOES = f; return retval;}
+ glDiscardFramebufferEXT_t set_glDiscardFramebufferEXT(glDiscardFramebufferEXT_t f) { glDiscardFramebufferEXT_t retval = glDiscardFramebufferEXT; glDiscardFramebufferEXT = f; return retval;}
+ glMultiDrawArraysEXT_t set_glMultiDrawArraysEXT(glMultiDrawArraysEXT_t f) { glMultiDrawArraysEXT_t retval = glMultiDrawArraysEXT; glMultiDrawArraysEXT = f; return retval;}
+ glMultiDrawElementsEXT_t set_glMultiDrawElementsEXT(glMultiDrawElementsEXT_t f) { glMultiDrawElementsEXT_t retval = glMultiDrawElementsEXT; glMultiDrawElementsEXT = f; return retval;}
+ glClipPlanefIMG_t set_glClipPlanefIMG(glClipPlanefIMG_t f) { glClipPlanefIMG_t retval = glClipPlanefIMG; glClipPlanefIMG = f; return retval;}
+ glClipPlanexIMG_t set_glClipPlanexIMG(glClipPlanexIMG_t f) { glClipPlanexIMG_t retval = glClipPlanexIMG; glClipPlanexIMG = f; return retval;}
+ glRenderbufferStorageMultisampleIMG_t set_glRenderbufferStorageMultisampleIMG(glRenderbufferStorageMultisampleIMG_t f) { glRenderbufferStorageMultisampleIMG_t retval = glRenderbufferStorageMultisampleIMG; glRenderbufferStorageMultisampleIMG = f; return retval;}
+ glFramebufferTexture2DMultisampleIMG_t set_glFramebufferTexture2DMultisampleIMG(glFramebufferTexture2DMultisampleIMG_t f) { glFramebufferTexture2DMultisampleIMG_t retval = glFramebufferTexture2DMultisampleIMG; glFramebufferTexture2DMultisampleIMG = f; return retval;}
+ glDeleteFencesNV_t set_glDeleteFencesNV(glDeleteFencesNV_t f) { glDeleteFencesNV_t retval = glDeleteFencesNV; glDeleteFencesNV = f; return retval;}
+ glGenFencesNV_t set_glGenFencesNV(glGenFencesNV_t f) { glGenFencesNV_t retval = glGenFencesNV; glGenFencesNV = f; return retval;}
+ glIsFenceNV_t set_glIsFenceNV(glIsFenceNV_t f) { glIsFenceNV_t retval = glIsFenceNV; glIsFenceNV = f; return retval;}
+ glTestFenceNV_t set_glTestFenceNV(glTestFenceNV_t f) { glTestFenceNV_t retval = glTestFenceNV; glTestFenceNV = f; return retval;}
+ glGetFenceivNV_t set_glGetFenceivNV(glGetFenceivNV_t f) { glGetFenceivNV_t retval = glGetFenceivNV; glGetFenceivNV = f; return retval;}
+ glFinishFenceNV_t set_glFinishFenceNV(glFinishFenceNV_t f) { glFinishFenceNV_t retval = glFinishFenceNV; glFinishFenceNV = f; return retval;}
+ glSetFenceNV_t set_glSetFenceNV(glSetFenceNV_t f) { glSetFenceNV_t retval = glSetFenceNV; glSetFenceNV = f; return retval;}
+ glGetDriverControlsQCOM_t set_glGetDriverControlsQCOM(glGetDriverControlsQCOM_t f) { glGetDriverControlsQCOM_t retval = glGetDriverControlsQCOM; glGetDriverControlsQCOM = f; return retval;}
+ glGetDriverControlStringQCOM_t set_glGetDriverControlStringQCOM(glGetDriverControlStringQCOM_t f) { glGetDriverControlStringQCOM_t retval = glGetDriverControlStringQCOM; glGetDriverControlStringQCOM = f; return retval;}
+ glEnableDriverControlQCOM_t set_glEnableDriverControlQCOM(glEnableDriverControlQCOM_t f) { glEnableDriverControlQCOM_t retval = glEnableDriverControlQCOM; glEnableDriverControlQCOM = f; return retval;}
+ glDisableDriverControlQCOM_t set_glDisableDriverControlQCOM(glDisableDriverControlQCOM_t f) { glDisableDriverControlQCOM_t retval = glDisableDriverControlQCOM; glDisableDriverControlQCOM = f; return retval;}
+ glExtGetTexturesQCOM_t set_glExtGetTexturesQCOM(glExtGetTexturesQCOM_t f) { glExtGetTexturesQCOM_t retval = glExtGetTexturesQCOM; glExtGetTexturesQCOM = f; return retval;}
+ glExtGetBuffersQCOM_t set_glExtGetBuffersQCOM(glExtGetBuffersQCOM_t f) { glExtGetBuffersQCOM_t retval = glExtGetBuffersQCOM; glExtGetBuffersQCOM = f; return retval;}
+ glExtGetRenderbuffersQCOM_t set_glExtGetRenderbuffersQCOM(glExtGetRenderbuffersQCOM_t f) { glExtGetRenderbuffersQCOM_t retval = glExtGetRenderbuffersQCOM; glExtGetRenderbuffersQCOM = f; return retval;}
+ glExtGetFramebuffersQCOM_t set_glExtGetFramebuffersQCOM(glExtGetFramebuffersQCOM_t f) { glExtGetFramebuffersQCOM_t retval = glExtGetFramebuffersQCOM; glExtGetFramebuffersQCOM = f; return retval;}
+ glExtGetTexLevelParameterivQCOM_t set_glExtGetTexLevelParameterivQCOM(glExtGetTexLevelParameterivQCOM_t f) { glExtGetTexLevelParameterivQCOM_t retval = glExtGetTexLevelParameterivQCOM; glExtGetTexLevelParameterivQCOM = f; return retval;}
+ glExtTexObjectStateOverrideiQCOM_t set_glExtTexObjectStateOverrideiQCOM(glExtTexObjectStateOverrideiQCOM_t f) { glExtTexObjectStateOverrideiQCOM_t retval = glExtTexObjectStateOverrideiQCOM; glExtTexObjectStateOverrideiQCOM = f; return retval;}
+ glExtGetTexSubImageQCOM_t set_glExtGetTexSubImageQCOM(glExtGetTexSubImageQCOM_t f) { glExtGetTexSubImageQCOM_t retval = glExtGetTexSubImageQCOM; glExtGetTexSubImageQCOM = f; return retval;}
+ glExtGetBufferPointervQCOM_t set_glExtGetBufferPointervQCOM(glExtGetBufferPointervQCOM_t f) { glExtGetBufferPointervQCOM_t retval = glExtGetBufferPointervQCOM; glExtGetBufferPointervQCOM = f; return retval;}
+ glExtGetShadersQCOM_t set_glExtGetShadersQCOM(glExtGetShadersQCOM_t f) { glExtGetShadersQCOM_t retval = glExtGetShadersQCOM; glExtGetShadersQCOM = f; return retval;}
+ glExtGetProgramsQCOM_t set_glExtGetProgramsQCOM(glExtGetProgramsQCOM_t f) { glExtGetProgramsQCOM_t retval = glExtGetProgramsQCOM; glExtGetProgramsQCOM = f; return retval;}
+ glExtIsProgramBinaryQCOM_t set_glExtIsProgramBinaryQCOM(glExtIsProgramBinaryQCOM_t f) { glExtIsProgramBinaryQCOM_t retval = glExtIsProgramBinaryQCOM; glExtIsProgramBinaryQCOM = f; return retval;}
+ glExtGetProgramBinarySourceQCOM_t set_glExtGetProgramBinarySourceQCOM(glExtGetProgramBinarySourceQCOM_t f) { glExtGetProgramBinarySourceQCOM_t retval = glExtGetProgramBinarySourceQCOM; glExtGetProgramBinarySourceQCOM = f; return retval;}
+ glStartTilingQCOM_t set_glStartTilingQCOM(glStartTilingQCOM_t f) { glStartTilingQCOM_t retval = glStartTilingQCOM; glStartTilingQCOM = f; return retval;}
+ glEndTilingQCOM_t set_glEndTilingQCOM(glEndTilingQCOM_t f) { glEndTilingQCOM_t retval = glEndTilingQCOM; glEndTilingQCOM = f; return retval;}
+};
+
+gles_dispatch *create_gles_dispatch(void *gles_andorid);
+
+#endif
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/gles_emul.cfg b/tools/emulator/opengl/tests/gles_android_wrapper/gles_emul.cfg
new file mode 100644
index 0000000..a837807
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/gles_emul.cfg
@@ -0,0 +1,7 @@
+angeles
+my-tritex
+org.zeroxlab.benchmark
+com.cooliris.media
+com.polarbit.waveblazerlite
+test-opengl-gl2_basic
+com.trendy.ddapp
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/gles_ftable.h b/tools/emulator/opengl/tests/gles_android_wrapper/gles_ftable.h
new file mode 100644
index 0000000..1895b18
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/gles_ftable.h
@@ -0,0 +1,292 @@
+/*
+* 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.
+*/
+static struct _gles_funcs_by_name {
+ const char *name;
+ void *proc;
+} gles_funcs_by_name[] = {
+ {"glAlphaFunc", (void *)glAlphaFunc},
+ {"glClearColor", (void *)glClearColor},
+ {"glClearDepthf", (void *)glClearDepthf},
+ {"glClipPlanef", (void *)glClipPlanef},
+ {"glColor4f", (void *)glColor4f},
+ {"glDepthRangef", (void *)glDepthRangef},
+ {"glFogf", (void *)glFogf},
+ {"glFogfv", (void *)glFogfv},
+ {"glFrustumf", (void *)glFrustumf},
+ {"glGetClipPlanef", (void *)glGetClipPlanef},
+ {"glGetFloatv", (void *)glGetFloatv},
+ {"glGetLightfv", (void *)glGetLightfv},
+ {"glGetMaterialfv", (void *)glGetMaterialfv},
+ {"glGetTexEnvfv", (void *)glGetTexEnvfv},
+ {"glGetTexParameterfv", (void *)glGetTexParameterfv},
+ {"glLightModelf", (void *)glLightModelf},
+ {"glLightModelfv", (void *)glLightModelfv},
+ {"glLightf", (void *)glLightf},
+ {"glLightfv", (void *)glLightfv},
+ {"glLineWidth", (void *)glLineWidth},
+ {"glLoadMatrixf", (void *)glLoadMatrixf},
+ {"glMaterialf", (void *)glMaterialf},
+ {"glMaterialfv", (void *)glMaterialfv},
+ {"glMultMatrixf", (void *)glMultMatrixf},
+ {"glMultiTexCoord4f", (void *)glMultiTexCoord4f},
+ {"glNormal3f", (void *)glNormal3f},
+ {"glOrthof", (void *)glOrthof},
+ {"glPointParameterf", (void *)glPointParameterf},
+ {"glPointParameterfv", (void *)glPointParameterfv},
+ {"glPointSize", (void *)glPointSize},
+ {"glPolygonOffset", (void *)glPolygonOffset},
+ {"glRotatef", (void *)glRotatef},
+ {"glScalef", (void *)glScalef},
+ {"glTexEnvf", (void *)glTexEnvf},
+ {"glTexEnvfv", (void *)glTexEnvfv},
+ {"glTexParameterf", (void *)glTexParameterf},
+ {"glTexParameterfv", (void *)glTexParameterfv},
+ {"glTranslatef", (void *)glTranslatef},
+ {"glActiveTexture", (void *)glActiveTexture},
+ {"glAlphaFuncx", (void *)glAlphaFuncx},
+ {"glBindBuffer", (void *)glBindBuffer},
+ {"glBindTexture", (void *)glBindTexture},
+ {"glBlendFunc", (void *)glBlendFunc},
+ {"glBufferData", (void *)glBufferData},
+ {"glBufferSubData", (void *)glBufferSubData},
+ {"glClear", (void *)glClear},
+ {"glClearColorx", (void *)glClearColorx},
+ {"glClearDepthx", (void *)glClearDepthx},
+ {"glClearStencil", (void *)glClearStencil},
+ {"glClientActiveTexture", (void *)glClientActiveTexture},
+ {"glClipPlanex", (void *)glClipPlanex},
+ {"glColor4ub", (void *)glColor4ub},
+ {"glColor4x", (void *)glColor4x},
+ {"glColorMask", (void *)glColorMask},
+ {"glColorPointer", (void *)glColorPointer},
+ {"glCompressedTexImage2D", (void *)glCompressedTexImage2D},
+ {"glCompressedTexSubImage2D", (void *)glCompressedTexSubImage2D},
+ {"glCopyTexImage2D", (void *)glCopyTexImage2D},
+ {"glCopyTexSubImage2D", (void *)glCopyTexSubImage2D},
+ {"glCullFace", (void *)glCullFace},
+ {"glDeleteBuffers", (void *)glDeleteBuffers},
+ {"glDeleteTextures", (void *)glDeleteTextures},
+ {"glDepthFunc", (void *)glDepthFunc},
+ {"glDepthMask", (void *)glDepthMask},
+ {"glDepthRangex", (void *)glDepthRangex},
+ {"glDisable", (void *)glDisable},
+ {"glDisableClientState", (void *)glDisableClientState},
+ {"glDrawArrays", (void *)glDrawArrays},
+ {"glDrawElements", (void *)glDrawElements},
+ {"glEnable", (void *)glEnable},
+ {"glEnableClientState", (void *)glEnableClientState},
+ {"glFinish", (void *)glFinish},
+ {"glFlush", (void *)glFlush},
+ {"glFogx", (void *)glFogx},
+ {"glFogxv", (void *)glFogxv},
+ {"glFrontFace", (void *)glFrontFace},
+ {"glFrustumx", (void *)glFrustumx},
+ {"glGetBooleanv", (void *)glGetBooleanv},
+ {"glGetBufferParameteriv", (void *)glGetBufferParameteriv},
+ {"glGetClipPlanex", (void *)glGetClipPlanex},
+ {"glGenBuffers", (void *)glGenBuffers},
+ {"glGenTextures", (void *)glGenTextures},
+ {"glGetError", (void *)glGetError},
+ {"glGetFixedv", (void *)glGetFixedv},
+ {"glGetIntegerv", (void *)glGetIntegerv},
+ {"glGetLightxv", (void *)glGetLightxv},
+ {"glGetMaterialxv", (void *)glGetMaterialxv},
+ {"glGetPointerv", (void *)glGetPointerv},
+ {"glGetString", (void *)glGetString},
+ {"glGetTexEnviv", (void *)glGetTexEnviv},
+ {"glGetTexEnvxv", (void *)glGetTexEnvxv},
+ {"glGetTexParameteriv", (void *)glGetTexParameteriv},
+ {"glGetTexParameterxv", (void *)glGetTexParameterxv},
+ {"glHint", (void *)glHint},
+ {"glIsBuffer", (void *)glIsBuffer},
+ {"glIsEnabled", (void *)glIsEnabled},
+ {"glIsTexture", (void *)glIsTexture},
+ {"glLightModelx", (void *)glLightModelx},
+ {"glLightModelxv", (void *)glLightModelxv},
+ {"glLightx", (void *)glLightx},
+ {"glLightxv", (void *)glLightxv},
+ {"glLineWidthx", (void *)glLineWidthx},
+ {"glLoadIdentity", (void *)glLoadIdentity},
+ {"glLoadMatrixx", (void *)glLoadMatrixx},
+ {"glLogicOp", (void *)glLogicOp},
+ {"glMaterialx", (void *)glMaterialx},
+ {"glMaterialxv", (void *)glMaterialxv},
+ {"glMatrixMode", (void *)glMatrixMode},
+ {"glMultMatrixx", (void *)glMultMatrixx},
+ {"glMultiTexCoord4x", (void *)glMultiTexCoord4x},
+ {"glNormal3x", (void *)glNormal3x},
+ {"glNormalPointer", (void *)glNormalPointer},
+ {"glOrthox", (void *)glOrthox},
+ {"glPixelStorei", (void *)glPixelStorei},
+ {"glPointParameterx", (void *)glPointParameterx},
+ {"glPointParameterxv", (void *)glPointParameterxv},
+ {"glPointSizex", (void *)glPointSizex},
+ {"glPolygonOffsetx", (void *)glPolygonOffsetx},
+ {"glPopMatrix", (void *)glPopMatrix},
+ {"glPushMatrix", (void *)glPushMatrix},
+ {"glReadPixels", (void *)glReadPixels},
+ {"glRotatex", (void *)glRotatex},
+ {"glSampleCoverage", (void *)glSampleCoverage},
+ {"glSampleCoveragex", (void *)glSampleCoveragex},
+ {"glScalex", (void *)glScalex},
+ {"glScissor", (void *)glScissor},
+ {"glShadeModel", (void *)glShadeModel},
+ {"glStencilFunc", (void *)glStencilFunc},
+ {"glStencilMask", (void *)glStencilMask},
+ {"glStencilOp", (void *)glStencilOp},
+ {"glTexCoordPointer", (void *)glTexCoordPointer},
+ {"glTexEnvi", (void *)glTexEnvi},
+ {"glTexEnvx", (void *)glTexEnvx},
+ {"glTexEnviv", (void *)glTexEnviv},
+ {"glTexEnvxv", (void *)glTexEnvxv},
+ {"glTexImage2D", (void *)glTexImage2D},
+ {"glTexParameteri", (void *)glTexParameteri},
+ {"glTexParameterx", (void *)glTexParameterx},
+ {"glTexParameteriv", (void *)glTexParameteriv},
+ {"glTexParameterxv", (void *)glTexParameterxv},
+ {"glTexSubImage2D", (void *)glTexSubImage2D},
+ {"glTranslatex", (void *)glTranslatex},
+ {"glVertexPointer", (void *)glVertexPointer},
+ {"glViewport", (void *)glViewport},
+ {"glPointSizePointerOES", (void *)glPointSizePointerOES},
+ {"glBlendEquationSeparateOES", (void *)glBlendEquationSeparateOES},
+ {"glBlendFuncSeparateOES", (void *)glBlendFuncSeparateOES},
+ {"glBlendEquationOES", (void *)glBlendEquationOES},
+ {"glDrawTexsOES", (void *)glDrawTexsOES},
+ {"glDrawTexiOES", (void *)glDrawTexiOES},
+ {"glDrawTexxOES", (void *)glDrawTexxOES},
+ {"glDrawTexsvOES", (void *)glDrawTexsvOES},
+ {"glDrawTexivOES", (void *)glDrawTexivOES},
+ {"glDrawTexxvOES", (void *)glDrawTexxvOES},
+ {"glDrawTexfOES", (void *)glDrawTexfOES},
+ {"glDrawTexfvOES", (void *)glDrawTexfvOES},
+ {"glEGLImageTargetTexture2DOES", (void *)glEGLImageTargetTexture2DOES},
+ {"glEGLImageTargetRenderbufferStorageOES", (void *)glEGLImageTargetRenderbufferStorageOES},
+ {"glAlphaFuncxOES", (void *)glAlphaFuncxOES},
+ {"glClearColorxOES", (void *)glClearColorxOES},
+ {"glClearDepthxOES", (void *)glClearDepthxOES},
+ {"glClipPlanexOES", (void *)glClipPlanexOES},
+ {"glColor4xOES", (void *)glColor4xOES},
+ {"glDepthRangexOES", (void *)glDepthRangexOES},
+ {"glFogxOES", (void *)glFogxOES},
+ {"glFogxvOES", (void *)glFogxvOES},
+ {"glFrustumxOES", (void *)glFrustumxOES},
+ {"glGetClipPlanexOES", (void *)glGetClipPlanexOES},
+ {"glGetFixedvOES", (void *)glGetFixedvOES},
+ {"glGetLightxvOES", (void *)glGetLightxvOES},
+ {"glGetMaterialxvOES", (void *)glGetMaterialxvOES},
+ {"glGetTexEnvxvOES", (void *)glGetTexEnvxvOES},
+ {"glGetTexParameterxvOES", (void *)glGetTexParameterxvOES},
+ {"glLightModelxOES", (void *)glLightModelxOES},
+ {"glLightModelxvOES", (void *)glLightModelxvOES},
+ {"glLightxOES", (void *)glLightxOES},
+ {"glLightxvOES", (void *)glLightxvOES},
+ {"glLineWidthxOES", (void *)glLineWidthxOES},
+ {"glLoadMatrixxOES", (void *)glLoadMatrixxOES},
+ {"glMaterialxOES", (void *)glMaterialxOES},
+ {"glMaterialxvOES", (void *)glMaterialxvOES},
+ {"glMultMatrixxOES", (void *)glMultMatrixxOES},
+ {"glMultiTexCoord4xOES", (void *)glMultiTexCoord4xOES},
+ {"glNormal3xOES", (void *)glNormal3xOES},
+ {"glOrthoxOES", (void *)glOrthoxOES},
+ {"glPointParameterxOES", (void *)glPointParameterxOES},
+ {"glPointParameterxvOES", (void *)glPointParameterxvOES},
+ {"glPointSizexOES", (void *)glPointSizexOES},
+ {"glPolygonOffsetxOES", (void *)glPolygonOffsetxOES},
+ {"glRotatexOES", (void *)glRotatexOES},
+ {"glSampleCoveragexOES", (void *)glSampleCoveragexOES},
+ {"glScalexOES", (void *)glScalexOES},
+ {"glTexEnvxOES", (void *)glTexEnvxOES},
+ {"glTexEnvxvOES", (void *)glTexEnvxvOES},
+ {"glTexParameterxOES", (void *)glTexParameterxOES},
+ {"glTexParameterxvOES", (void *)glTexParameterxvOES},
+ {"glTranslatexOES", (void *)glTranslatexOES},
+ {"glIsRenderbufferOES", (void *)glIsRenderbufferOES},
+ {"glBindRenderbufferOES", (void *)glBindRenderbufferOES},
+ {"glDeleteRenderbuffersOES", (void *)glDeleteRenderbuffersOES},
+ {"glGenRenderbuffersOES", (void *)glGenRenderbuffersOES},
+ {"glRenderbufferStorageOES", (void *)glRenderbufferStorageOES},
+ {"glGetRenderbufferParameterivOES", (void *)glGetRenderbufferParameterivOES},
+ {"glIsFramebufferOES", (void *)glIsFramebufferOES},
+ {"glBindFramebufferOES", (void *)glBindFramebufferOES},
+ {"glDeleteFramebuffersOES", (void *)glDeleteFramebuffersOES},
+ {"glGenFramebuffersOES", (void *)glGenFramebuffersOES},
+ {"glCheckFramebufferStatusOES", (void *)glCheckFramebufferStatusOES},
+ {"glFramebufferRenderbufferOES", (void *)glFramebufferRenderbufferOES},
+ {"glFramebufferTexture2DOES", (void *)glFramebufferTexture2DOES},
+ {"glGetFramebufferAttachmentParameterivOES", (void *)glGetFramebufferAttachmentParameterivOES},
+ {"glGenerateMipmapOES", (void *)glGenerateMipmapOES},
+ {"glMapBufferOES", (void *)glMapBufferOES},
+ {"glUnmapBufferOES", (void *)glUnmapBufferOES},
+ {"glGetBufferPointervOES", (void *)glGetBufferPointervOES},
+ {"glCurrentPaletteMatrixOES", (void *)glCurrentPaletteMatrixOES},
+ {"glLoadPaletteFromModelViewMatrixOES", (void *)glLoadPaletteFromModelViewMatrixOES},
+ {"glMatrixIndexPointerOES", (void *)glMatrixIndexPointerOES},
+ {"glWeightPointerOES", (void *)glWeightPointerOES},
+ {"glQueryMatrixxOES", (void *)glQueryMatrixxOES},
+ {"glDepthRangefOES", (void *)glDepthRangefOES},
+ {"glFrustumfOES", (void *)glFrustumfOES},
+ {"glOrthofOES", (void *)glOrthofOES},
+ {"glClipPlanefOES", (void *)glClipPlanefOES},
+ {"glGetClipPlanefOES", (void *)glGetClipPlanefOES},
+ {"glClearDepthfOES", (void *)glClearDepthfOES},
+ {"glTexGenfOES", (void *)glTexGenfOES},
+ {"glTexGenfvOES", (void *)glTexGenfvOES},
+ {"glTexGeniOES", (void *)glTexGeniOES},
+ {"glTexGenivOES", (void *)glTexGenivOES},
+ {"glTexGenxOES", (void *)glTexGenxOES},
+ {"glTexGenxvOES", (void *)glTexGenxvOES},
+ {"glGetTexGenfvOES", (void *)glGetTexGenfvOES},
+ {"glGetTexGenivOES", (void *)glGetTexGenivOES},
+ {"glGetTexGenxvOES", (void *)glGetTexGenxvOES},
+ {"glBindVertexArrayOES", (void *)glBindVertexArrayOES},
+ {"glDeleteVertexArraysOES", (void *)glDeleteVertexArraysOES},
+ {"glGenVertexArraysOES", (void *)glGenVertexArraysOES},
+ {"glIsVertexArrayOES", (void *)glIsVertexArrayOES},
+ {"glDiscardFramebufferEXT", (void *)glDiscardFramebufferEXT},
+ {"glMultiDrawArraysEXT", (void *)glMultiDrawArraysEXT},
+ {"glMultiDrawElementsEXT", (void *)glMultiDrawElementsEXT},
+ {"glClipPlanefIMG", (void *)glClipPlanefIMG},
+ {"glClipPlanexIMG", (void *)glClipPlanexIMG},
+ {"glRenderbufferStorageMultisampleIMG", (void *)glRenderbufferStorageMultisampleIMG},
+ {"glFramebufferTexture2DMultisampleIMG", (void *)glFramebufferTexture2DMultisampleIMG},
+ {"glDeleteFencesNV", (void *)glDeleteFencesNV},
+ {"glGenFencesNV", (void *)glGenFencesNV},
+ {"glIsFenceNV", (void *)glIsFenceNV},
+ {"glTestFenceNV", (void *)glTestFenceNV},
+ {"glGetFenceivNV", (void *)glGetFenceivNV},
+ {"glFinishFenceNV", (void *)glFinishFenceNV},
+ {"glSetFenceNV", (void *)glSetFenceNV},
+ {"glGetDriverControlsQCOM", (void *)glGetDriverControlsQCOM},
+ {"glGetDriverControlStringQCOM", (void *)glGetDriverControlStringQCOM},
+ {"glEnableDriverControlQCOM", (void *)glEnableDriverControlQCOM},
+ {"glDisableDriverControlQCOM", (void *)glDisableDriverControlQCOM},
+ {"glExtGetTexturesQCOM", (void *)glExtGetTexturesQCOM},
+ {"glExtGetBuffersQCOM", (void *)glExtGetBuffersQCOM},
+ {"glExtGetRenderbuffersQCOM", (void *)glExtGetRenderbuffersQCOM},
+ {"glExtGetFramebuffersQCOM", (void *)glExtGetFramebuffersQCOM},
+ {"glExtGetTexLevelParameterivQCOM", (void *)glExtGetTexLevelParameterivQCOM},
+ {"glExtTexObjectStateOverrideiQCOM", (void *)glExtTexObjectStateOverrideiQCOM},
+ {"glExtGetTexSubImageQCOM", (void *)glExtGetTexSubImageQCOM},
+ {"glExtGetBufferPointervQCOM", (void *)glExtGetBufferPointervQCOM},
+ {"glExtGetShadersQCOM", (void *)glExtGetShadersQCOM},
+ {"glExtGetProgramsQCOM", (void *)glExtGetProgramsQCOM},
+ {"glExtIsProgramBinaryQCOM", (void *)glExtIsProgramBinaryQCOM},
+ {"glExtGetProgramBinarySourceQCOM", (void *)glExtGetProgramBinarySourceQCOM},
+ {"glStartTilingQCOM", (void *)glStartTilingQCOM},
+ {"glEndTilingQCOM", (void *)glEndTilingQCOM}
+};
+static int gles_num_funcs = sizeof(gles_funcs_by_name) / sizeof(struct _gles_funcs_by_name);
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/gles_proc.h b/tools/emulator/opengl/tests/gles_android_wrapper/gles_proc.h
new file mode 100644
index 0000000..afd94b9
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/gles_proc.h
@@ -0,0 +1,296 @@
+/*
+* 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.
+*/
+#ifndef _GLES_PROC_H
+#define _GLES_PROC_H
+
+#include <GLES/gl.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GLES/glext.h>
+
+typedef void (* glAlphaFunc_t) (GLenum, GLclampf);
+typedef void (* glClearColor_t) (GLclampf, GLclampf, GLclampf, GLclampf);
+typedef void (* glClearDepthf_t) (GLclampf);
+typedef void (* glClipPlanef_t) (GLenum, const GLfloat*);
+typedef void (* glColor4f_t) (GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glDepthRangef_t) (GLclampf, GLclampf);
+typedef void (* glFogf_t) (GLenum, GLfloat);
+typedef void (* glFogfv_t) (GLenum, const GLfloat*);
+typedef void (* glFrustumf_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glGetClipPlanef_t) (GLenum, GLfloat*);
+typedef void (* glGetFloatv_t) (GLenum, GLfloat*);
+typedef void (* glGetLightfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetMaterialfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexEnvfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexParameterfv_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glLightModelf_t) (GLenum, GLfloat);
+typedef void (* glLightModelfv_t) (GLenum, const GLfloat*);
+typedef void (* glLightf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glLightfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glLineWidth_t) (GLfloat);
+typedef void (* glLoadMatrixf_t) (const GLfloat*);
+typedef void (* glMaterialf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glMaterialfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glMultMatrixf_t) (const GLfloat*);
+typedef void (* glMultiTexCoord4f_t) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glNormal3f_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glOrthof_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glPointParameterf_t) (GLenum, GLfloat);
+typedef void (* glPointParameterfv_t) (GLenum, const GLfloat*);
+typedef void (* glPointSize_t) (GLfloat);
+typedef void (* glPolygonOffset_t) (GLfloat, GLfloat);
+typedef void (* glRotatef_t) (GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glScalef_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glTexEnvf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexEnvfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTexParameterf_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexParameterfv_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTranslatef_t) (GLfloat, GLfloat, GLfloat);
+typedef void (* glActiveTexture_t) (GLenum);
+typedef void (* glAlphaFuncx_t) (GLenum, GLclampx);
+typedef void (* glBindBuffer_t) (GLenum, GLuint);
+typedef void (* glBindTexture_t) (GLenum, GLuint);
+typedef void (* glBlendFunc_t) (GLenum, GLenum);
+typedef void (* glBufferData_t) (GLenum, GLsizeiptr, const GLvoid*, GLenum);
+typedef void (* glBufferSubData_t) (GLenum, GLintptr, GLsizeiptr, const GLvoid*);
+typedef void (* glClear_t) (GLbitfield);
+typedef void (* glClearColorx_t) (GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (* glClearDepthx_t) (GLclampx);
+typedef void (* glClearStencil_t) (GLint);
+typedef void (* glClientActiveTexture_t) (GLenum);
+typedef void (* glClipPlanex_t) (GLenum, const GLfixed*);
+typedef void (* glColor4ub_t) (GLubyte, GLubyte, GLubyte, GLubyte);
+typedef void (* glColor4x_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glColorMask_t) (GLboolean, GLboolean, GLboolean, GLboolean);
+typedef void (* glColorPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glCompressedTexImage2D_t) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*);
+typedef void (* glCompressedTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*);
+typedef void (* glCopyTexImage2D_t) (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+typedef void (* glCopyTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+typedef void (* glCullFace_t) (GLenum);
+typedef void (* glDeleteBuffers_t) (GLsizei, const GLuint*);
+typedef void (* glDeleteTextures_t) (GLsizei, const GLuint*);
+typedef void (* glDepthFunc_t) (GLenum);
+typedef void (* glDepthMask_t) (GLboolean);
+typedef void (* glDepthRangex_t) (GLclampx, GLclampx);
+typedef void (* glDisable_t) (GLenum);
+typedef void (* glDisableClientState_t) (GLenum);
+typedef void (* glDrawArrays_t) (GLenum, GLint, GLsizei);
+typedef void (* glDrawElements_t) (GLenum, GLsizei, GLenum, const GLvoid*);
+typedef void (* glEnable_t) (GLenum);
+typedef void (* glEnableClientState_t) (GLenum);
+typedef void (* glFinish_t) ();
+typedef void (* glFlush_t) ();
+typedef void (* glFogx_t) (GLenum, GLfixed);
+typedef void (* glFogxv_t) (GLenum, const GLfixed*);
+typedef void (* glFrontFace_t) (GLenum);
+typedef void (* glFrustumx_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glGetBooleanv_t) (GLenum, GLboolean*);
+typedef void (* glGetBufferParameteriv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetClipPlanex_t) (GLenum, GLfixed*);
+typedef void (* glGenBuffers_t) (GLsizei, GLuint*);
+typedef void (* glGenTextures_t) (GLsizei, GLuint*);
+typedef GLenum (* glGetError_t) ();
+typedef void (* glGetFixedv_t) (GLenum, GLfixed*);
+typedef void (* glGetIntegerv_t) (GLenum, GLint*);
+typedef void (* glGetLightxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetMaterialxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetPointerv_t) (GLenum, GLvoid**);
+typedef const GLubyte* (* glGetString_t) (GLenum);
+typedef void (* glGetTexEnviv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexEnvxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexParameteriv_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexParameterxv_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glHint_t) (GLenum, GLenum);
+typedef GLboolean (* glIsBuffer_t) (GLuint);
+typedef GLboolean (* glIsEnabled_t) (GLenum);
+typedef GLboolean (* glIsTexture_t) (GLuint);
+typedef void (* glLightModelx_t) (GLenum, GLfixed);
+typedef void (* glLightModelxv_t) (GLenum, const GLfixed*);
+typedef void (* glLightx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glLightxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glLineWidthx_t) (GLfixed);
+typedef void (* glLoadIdentity_t) ();
+typedef void (* glLoadMatrixx_t) (const GLfixed*);
+typedef void (* glLogicOp_t) (GLenum);
+typedef void (* glMaterialx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glMaterialxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glMatrixMode_t) (GLenum);
+typedef void (* glMultMatrixx_t) (const GLfixed*);
+typedef void (* glMultiTexCoord4x_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glNormal3x_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glNormalPointer_t) (GLenum, GLsizei, const GLvoid*);
+typedef void (* glOrthox_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glPixelStorei_t) (GLenum, GLint);
+typedef void (* glPointParameterx_t) (GLenum, GLfixed);
+typedef void (* glPointParameterxv_t) (GLenum, const GLfixed*);
+typedef void (* glPointSizex_t) (GLfixed);
+typedef void (* glPolygonOffsetx_t) (GLfixed, GLfixed);
+typedef void (* glPopMatrix_t) ();
+typedef void (* glPushMatrix_t) ();
+typedef void (* glReadPixels_t) (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (* glRotatex_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glSampleCoverage_t) (GLclampf, GLboolean);
+typedef void (* glSampleCoveragex_t) (GLclampx, GLboolean);
+typedef void (* glScalex_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glScissor_t) (GLint, GLint, GLsizei, GLsizei);
+typedef void (* glShadeModel_t) (GLenum);
+typedef void (* glStencilFunc_t) (GLenum, GLint, GLuint);
+typedef void (* glStencilMask_t) (GLuint);
+typedef void (* glStencilOp_t) (GLenum, GLenum, GLenum);
+typedef void (* glTexCoordPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glTexEnvi_t) (GLenum, GLenum, GLint);
+typedef void (* glTexEnvx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexEnviv_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexEnvxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexImage2D_t) (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
+typedef void (* glTexParameteri_t) (GLenum, GLenum, GLint);
+typedef void (* glTexParameterx_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexParameteriv_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexParameterxv_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*);
+typedef void (* glTranslatex_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glVertexPointer_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glViewport_t) (GLint, GLint, GLsizei, GLsizei);
+typedef void (* glPointSizePointerOES_t) (GLenum, GLsizei, const GLvoid*);
+typedef void (* glBlendEquationSeparateOES_t) (GLenum, GLenum);
+typedef void (* glBlendFuncSeparateOES_t) (GLenum, GLenum, GLenum, GLenum);
+typedef void (* glBlendEquationOES_t) (GLenum);
+typedef void (* glDrawTexsOES_t) (GLshort, GLshort, GLshort, GLshort, GLshort);
+typedef void (* glDrawTexiOES_t) (GLint, GLint, GLint, GLint, GLint);
+typedef void (* glDrawTexxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glDrawTexsvOES_t) (const GLshort*);
+typedef void (* glDrawTexivOES_t) (const GLint*);
+typedef void (* glDrawTexxvOES_t) (const GLfixed*);
+typedef void (* glDrawTexfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glDrawTexfvOES_t) (const GLfloat*);
+typedef void (* glEGLImageTargetTexture2DOES_t) (GLenum, GLeglImageOES);
+typedef void (* glEGLImageTargetRenderbufferStorageOES_t) (GLenum, GLeglImageOES);
+typedef void (* glAlphaFuncxOES_t) (GLenum, GLclampx);
+typedef void (* glClearColorxOES_t) (GLclampx, GLclampx, GLclampx, GLclampx);
+typedef void (* glClearDepthxOES_t) (GLclampx);
+typedef void (* glClipPlanexOES_t) (GLenum, const GLfixed*);
+typedef void (* glColor4xOES_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glDepthRangexOES_t) (GLclampx, GLclampx);
+typedef void (* glFogxOES_t) (GLenum, GLfixed);
+typedef void (* glFogxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glFrustumxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glGetClipPlanexOES_t) (GLenum, GLfixed*);
+typedef void (* glGetFixedvOES_t) (GLenum, GLfixed*);
+typedef void (* glGetLightxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetMaterialxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexEnvxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glGetTexParameterxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glLightModelxOES_t) (GLenum, GLfixed);
+typedef void (* glLightModelxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glLightxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glLightxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glLineWidthxOES_t) (GLfixed);
+typedef void (* glLoadMatrixxOES_t) (const GLfixed*);
+typedef void (* glMaterialxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glMaterialxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glMultMatrixxOES_t) (const GLfixed*);
+typedef void (* glMultiTexCoord4xOES_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glNormal3xOES_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glOrthoxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glPointParameterxOES_t) (GLenum, GLfixed);
+typedef void (* glPointParameterxvOES_t) (GLenum, const GLfixed*);
+typedef void (* glPointSizexOES_t) (GLfixed);
+typedef void (* glPolygonOffsetxOES_t) (GLfixed, GLfixed);
+typedef void (* glRotatexOES_t) (GLfixed, GLfixed, GLfixed, GLfixed);
+typedef void (* glSampleCoveragexOES_t) (GLclampx, GLboolean);
+typedef void (* glScalexOES_t) (GLfixed, GLfixed, GLfixed);
+typedef void (* glTexEnvxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexEnvxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTexParameterxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexParameterxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glTranslatexOES_t) (GLfixed, GLfixed, GLfixed);
+typedef GLboolean (* glIsRenderbufferOES_t) (GLuint);
+typedef void (* glBindRenderbufferOES_t) (GLenum, GLuint);
+typedef void (* glDeleteRenderbuffersOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenRenderbuffersOES_t) (GLsizei, GLuint*);
+typedef void (* glRenderbufferStorageOES_t) (GLenum, GLenum, GLsizei, GLsizei);
+typedef void (* glGetRenderbufferParameterivOES_t) (GLenum, GLenum, GLint*);
+typedef GLboolean (* glIsFramebufferOES_t) (GLuint);
+typedef void (* glBindFramebufferOES_t) (GLenum, GLuint);
+typedef void (* glDeleteFramebuffersOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenFramebuffersOES_t) (GLsizei, GLuint*);
+typedef GLenum (* glCheckFramebufferStatusOES_t) (GLenum);
+typedef void (* glFramebufferRenderbufferOES_t) (GLenum, GLenum, GLenum, GLuint);
+typedef void (* glFramebufferTexture2DOES_t) (GLenum, GLenum, GLenum, GLuint, GLint);
+typedef void (* glGetFramebufferAttachmentParameterivOES_t) (GLenum, GLenum, GLenum, GLint*);
+typedef void (* glGenerateMipmapOES_t) (GLenum);
+typedef void* (* glMapBufferOES_t) (GLenum, GLenum);
+typedef GLboolean (* glUnmapBufferOES_t) (GLenum);
+typedef void (* glGetBufferPointervOES_t) (GLenum, GLenum, GLvoid*);
+typedef void (* glCurrentPaletteMatrixOES_t) (GLuint);
+typedef void (* glLoadPaletteFromModelViewMatrixOES_t) ();
+typedef void (* glMatrixIndexPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef void (* glWeightPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*);
+typedef GLbitfield (* glQueryMatrixxOES_t) (GLfixed*, GLint*);
+typedef void (* glDepthRangefOES_t) (GLclampf, GLclampf);
+typedef void (* glFrustumfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glOrthofOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+typedef void (* glClipPlanefOES_t) (GLenum, const GLfloat*);
+typedef void (* glGetClipPlanefOES_t) (GLenum, GLfloat*);
+typedef void (* glClearDepthfOES_t) (GLclampf);
+typedef void (* glTexGenfOES_t) (GLenum, GLenum, GLfloat);
+typedef void (* glTexGenfvOES_t) (GLenum, GLenum, const GLfloat*);
+typedef void (* glTexGeniOES_t) (GLenum, GLenum, GLint);
+typedef void (* glTexGenivOES_t) (GLenum, GLenum, const GLint*);
+typedef void (* glTexGenxOES_t) (GLenum, GLenum, GLfixed);
+typedef void (* glTexGenxvOES_t) (GLenum, GLenum, const GLfixed*);
+typedef void (* glGetTexGenfvOES_t) (GLenum, GLenum, GLfloat*);
+typedef void (* glGetTexGenivOES_t) (GLenum, GLenum, GLint*);
+typedef void (* glGetTexGenxvOES_t) (GLenum, GLenum, GLfixed*);
+typedef void (* glBindVertexArrayOES_t) (GLuint);
+typedef void (* glDeleteVertexArraysOES_t) (GLsizei, const GLuint*);
+typedef void (* glGenVertexArraysOES_t) (GLsizei, GLuint*);
+typedef GLboolean (* glIsVertexArrayOES_t) (GLuint);
+typedef void (* glDiscardFramebufferEXT_t) (GLenum, GLsizei, const GLenum*);
+typedef void (* glMultiDrawArraysEXT_t) (GLenum, GLint*, GLsizei*, GLsizei);
+typedef void (* glMultiDrawElementsEXT_t) (GLenum, const GLsizei*, GLenum, const GLvoid**, GLsizei);
+typedef void (* glClipPlanefIMG_t) (GLenum, const GLfloat*);
+typedef void (* glClipPlanexIMG_t) (GLenum, const GLfixed*);
+typedef void (* glRenderbufferStorageMultisampleIMG_t) (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+typedef void (* glFramebufferTexture2DMultisampleIMG_t) (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
+typedef void (* glDeleteFencesNV_t) (GLsizei, const GLuint*);
+typedef void (* glGenFencesNV_t) (GLsizei, GLuint*);
+typedef GLboolean (* glIsFenceNV_t) (GLuint);
+typedef GLboolean (* glTestFenceNV_t) (GLuint);
+typedef void (* glGetFenceivNV_t) (GLuint, GLenum, GLint*);
+typedef void (* glFinishFenceNV_t) (GLuint);
+typedef void (* glSetFenceNV_t) (GLuint, GLenum);
+typedef void (* glGetDriverControlsQCOM_t) (GLint*, GLsizei, GLuint*);
+typedef void (* glGetDriverControlStringQCOM_t) (GLuint, GLsizei, GLsizei*, GLchar*);
+typedef void (* glEnableDriverControlQCOM_t) (GLuint);
+typedef void (* glDisableDriverControlQCOM_t) (GLuint);
+typedef void (* glExtGetTexturesQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetBuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetRenderbuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetFramebuffersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetTexLevelParameterivQCOM_t) (GLuint, GLenum, GLint, GLenum, GLint*);
+typedef void (* glExtTexObjectStateOverrideiQCOM_t) (GLenum, GLenum, GLint);
+typedef void (* glExtGetTexSubImageQCOM_t) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLvoid*);
+typedef void (* glExtGetBufferPointervQCOM_t) (GLenum, GLvoid**);
+typedef void (* glExtGetShadersQCOM_t) (GLuint*, GLint, GLint*);
+typedef void (* glExtGetProgramsQCOM_t) (GLuint*, GLint, GLint*);
+typedef GLboolean (* glExtIsProgramBinaryQCOM_t) (GLuint);
+typedef void (* glExtGetProgramBinarySourceQCOM_t) (GLuint, GLenum, GLchar*, GLint*);
+typedef void (* glStartTilingQCOM_t) (GLuint, GLuint, GLuint, GLuint, GLbitfield);
+typedef void (* glEndTilingQCOM_t) (GLbitfield);
+
+
+#endif
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp
new file mode 100644
index 0000000..41e7b7a
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/glesv1_emul_ifc.cpp
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+#include "ApiInitializer.h"
+#include <dlfcn.h>
+#include "gl_wrapper_context.h"
+
+extern "C" {
+ gl_wrapper_context_t *createFromLib(void *solib, gl_wrapper_context_t *(*accessor)());
+}
+
+gl_wrapper_context_t * createFromLib(void *solib, gl_wrapper_context_t *(accessor)())
+{
+ gl_wrapper_context_t *ctx = new gl_wrapper_context_t;
+ if (ctx == NULL) {
+ return NULL;
+ }
+ ApiInitializer *initializer = new ApiInitializer(solib);
+ ctx->initDispatchByName(ApiInitializer::s_getProc, initializer);
+ gl_wrapper_context_t::setContextAccessor(accessor);
+ delete initializer;
+ return ctx;
+}
+
+
diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp
new file mode 100644
index 0000000..cf0dfed
--- /dev/null
+++ b/tools/emulator/opengl/tests/gles_android_wrapper/glesv2_emul_ifc.cpp
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+#include "ApiInitializer.h"
+#include <dlfcn.h>
+#include "gl2_wrapper_context.h"
+
+extern "C" {
+ gl2_wrapper_context_t *createFromLib(void *solib, gl2_wrapper_context_t *(*accessor)());
+}
+
+gl2_wrapper_context_t * createFromLib(void *solib, gl2_wrapper_context_t *(*accessor)())
+{
+ gl2_wrapper_context_t *ctx = new gl2_wrapper_context_t;
+ if (ctx == NULL) {
+ return NULL;
+ }
+ ApiInitializer *initializer = new ApiInitializer(solib);
+ ctx->initDispatchByName(ApiInitializer::s_getProc, initializer);
+ gl2_wrapper_context_t::setContextAccessor(accessor);
+ delete initializer;
+ return ctx;
+}
+
+
+
diff --git a/tools/emulator/opengl/tests/ut_renderer/Android.mk b/tools/emulator/opengl/tests/ut_renderer/Android.mk
new file mode 100644
index 0000000..fe8e7ac
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/Android.mk
@@ -0,0 +1,30 @@
+LOCAL_PATH:=$(call my-dir)
+
+ifeq ($(HOST_OS), linux)
+
+$(call emugl-begin-host-executable,ut_renderer)
+$(call emugl-import,libut_rendercontrol_dec libGLESv1_dec libGLESv2_dec libEGL_host_wrapper)
+
+LOCAL_SRC_FILES := ut_renderer.cpp \
+ RenderingThread.cpp \
+ ReadBuffer.cpp \
+ Renderer.cpp \
+ RendererContext.cpp \
+ RendererSurface.cpp \
+ X11Windowing.cpp
+
+# define PVR_WAR to support imgtec PVR opengl-ES implementation
+#
+# specifically this MACRO enables code that work arounds a bug
+# in the implementation where glTextureParameter(...,GL_TEXTURE_RECT,...)
+# is called would cause a crash if the texture dimensions have not been
+# defined yet.
+
+LOCAL_CFLAGS += -DPVR_WAR
+#LOCAL_CFLAGS += -g -O0
+
+LOCAL_LDLIBS += -lpthread -lX11 -lrt
+
+$(call emugl-end-module)
+
+endif # HOST_OS == linux
diff --git a/tools/emulator/opengl/tests/ut_renderer/NativeWindowing.h b/tools/emulator/opengl/tests/ut_renderer/NativeWindowing.h
new file mode 100644
index 0000000..9468066
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/NativeWindowing.h
@@ -0,0 +1,28 @@
+/*
+* 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.
+*/
+#ifndef _NATIVE_WINDOWING_H
+#define _NATIVE_WINDOWING_H
+
+#include <EGL/egl.h>
+
+class NativeWindowing {
+public:
+ virtual NativeDisplayType getNativeDisplay() = 0;
+ virtual NativeWindowType createNativeWindow(NativeDisplayType dpy, int width, int height) = 0;
+ virtual int destroyNativeWindow(NativeDisplayType dpy, NativeWindowType win) = 0;
+};
+
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp
new file mode 100644
index 0000000..661b4cc
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp
@@ -0,0 +1,53 @@
+/*
+* 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.
+*/
+#include "ReadBuffer.h"
+#include <string.h>
+#include <assert.h>
+
+ReadBuffer::ReadBuffer(TcpStream *stream, size_t bufsize)
+{
+ m_size = bufsize;
+ m_stream = stream;
+ m_buf = new unsigned char[m_size];
+ m_validData = 0;
+ m_readPtr = m_buf;
+}
+
+ReadBuffer::~ReadBuffer()
+{
+ delete m_buf;
+}
+
+int ReadBuffer::getData()
+{
+ if (m_validData > 0) {
+ memcpy(m_buf, m_readPtr, m_validData);
+ }
+ m_readPtr = m_buf;
+ // get fresh data into the buffer;
+ int stat = m_stream->recv(m_buf + m_validData, m_size - m_validData);
+ if (stat > 0) {
+ m_validData += (size_t) stat;
+ }
+ return stat;
+}
+
+void ReadBuffer::consume(size_t amount)
+{
+ assert(amount <= m_validData);
+ m_validData -= amount;
+ m_readPtr += amount;
+}
diff --git a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h
new file mode 100644
index 0000000..1b8f6fd
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h
@@ -0,0 +1,36 @@
+/*
+* 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.
+*/
+#ifndef _READ_BUFFER_H
+#define _READ_BUFFER_H
+
+#include "TcpStream.h"
+
+class ReadBuffer {
+public:
+ ReadBuffer(TcpStream *stream, size_t bufSize);
+ ~ReadBuffer();
+ int getData(); // get fresh data from the stream
+ unsigned char *buf() { return m_readPtr; } // return the next read location
+ size_t validData() { return m_validData; } // return the amount of valid data in readptr
+ void consume(size_t amount); // notify that 'amount' data has been consumed;
+private:
+ unsigned char *m_buf;
+ unsigned char *m_readPtr;
+ size_t m_size;
+ size_t m_validData;
+ TcpStream *m_stream;
+};
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp
new file mode 100644
index 0000000..22afadb
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp
@@ -0,0 +1,183 @@
+/*
+* 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "RenderingThread.h"
+#include "Renderer.h"
+
+// include operating-system dependent windowing system impelemntation
+#ifdef _WIN32
+# error "WINDOWS IS NOT SUPPORTED AT THE MOMENT"
+#elif defined __APPLE__
+# error "Apple OS-X IS NOT SUPPORTED"
+#elif defined (__unix__)
+# include "X11Windowing.h"
+#endif
+
+
+
+
+
+Renderer * Renderer::m_instance = NULL;
+
+Renderer * Renderer::instance()
+{
+ if (m_instance == NULL) m_instance = new Renderer;
+ return m_instance;
+}
+
+Renderer::Renderer()
+{
+ // Unix specific, use your platform specific windowing implementation
+#ifdef __unix__
+ m_nw = new X11Windowing;
+#endif
+
+ m_dpy = eglGetDisplay(m_nw->getNativeDisplay());
+ EGLint major, minor;
+ eglInitialize(m_dpy, &major, &minor);
+ fprintf(stderr, "egl initialized : %d.%d\n", major, minor);
+}
+
+int Renderer::createSurface(RenderingThread *thread, const ClientHandle & handle)
+{
+ android::Mutex::Autolock(this->m_mutex);
+
+ assert(m_surfaces.find(handle) == m_surfaces.end());
+ if (handle.handle == 0) {
+ fprintf(stderr, "trying to create surface for EGL_NO_SURFACE !!!\n");
+ return -1;
+ } else {
+ RendererSurface *surface = RendererSurface::create(m_dpy, RendererSurface::CONFIG_DEPTH, m_nw);
+ if (surface == NULL) {
+ printf("failed to create surface !!\n");
+ return -1;
+ }
+ m_surfaces.insert(SurfaceMap::value_type(handle, surface));
+ }
+ return 0;
+}
+
+int Renderer::destroySurface(RenderingThread *thread, const ClientHandle &handle)
+{
+ android::Mutex::Autolock(this->m_mutex);
+
+ SurfaceMap::iterator i = m_surfaces.find(handle);
+ if (i == m_surfaces.end()) {
+ printf("removing surface that doesn't exists\n");
+ return -1;
+ }
+ if (i->second->destroy(m_nw)) {
+ m_surfaces.erase(handle);
+ }
+ return 0;
+}
+
+int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle, ClientHandle shareCtx, int version)
+{
+ android::Mutex::Autolock(this->m_mutex);
+
+ assert(m_ctxs.find(handle) == m_ctxs.end());
+ RendererContext *shared = NULL;
+ if (shareCtx.handle != 0) {
+ ContextMap::iterator sctx = m_ctxs.find(shareCtx);
+ if (sctx != m_ctxs.end()) {
+ shared = sctx->second;
+ }
+ }
+
+ RendererContext *ctx =
+ RendererContext::create(m_dpy,
+ RendererSurface::getEglConfig(m_dpy, RendererSurface::CONFIG_DEPTH),
+ shared, version);
+ if (ctx == NULL) {
+ fprintf(stderr, "failed to create context\n");
+ return -1;
+ }
+ m_ctxs.insert(ContextMap::value_type(handle, ctx));
+ return 0;
+}
+
+int Renderer::destroyContext(RenderingThread *thread, const ClientHandle &handle)
+{
+ android::Mutex::Autolock(this->m_mutex);
+
+ ContextMap::iterator i = m_ctxs.find(handle);
+ if (i == m_ctxs.end()) {
+ printf("removing context that doesn't exists\n");
+ return -1;
+ }
+ if (i->second->destroy()) {
+ m_ctxs.erase(handle);
+ }
+ return 0;
+}
+
+int Renderer::makeCurrent(RenderingThread *thread,
+ const ClientHandle &drawSurface,
+ const ClientHandle &readSurface,
+ const ClientHandle & ctx)
+{
+ android::Mutex::Autolock(this->m_mutex);
+
+ RendererContext *currentContext = thread->currentContext();
+
+ ContextMap::iterator c = m_ctxs.find(ctx);
+ EGLContext eglContext;
+ if (ctx.handle != 0 && c != m_ctxs.end()) {
+ if (c->second != currentContext) {
+ // new context is set
+ if (currentContext != NULL) currentContext->unref();
+ c->second->ref();
+ eglContext = c->second->eglContext();
+ thread->setCurrentContext(c->second);
+ thread->glDecoder().setContextData(&c->second->decoderContextData());
+ thread->gl2Decoder().setContextData(&c->second->decoderContextData());
+ } else {
+ // same context is already set
+ eglContext = c->second->eglContext();
+ }
+ } else {
+ eglContext = EGL_NO_CONTEXT;
+ if (currentContext != NULL) currentContext->unref();
+ thread->setCurrentContext(NULL);
+ thread->glDecoder().setContextData(NULL);
+ thread->gl2Decoder().setContextData(NULL);
+ }
+
+ EGLSurface draw = EGL_NO_SURFACE;
+ EGLSurface read = EGL_NO_SURFACE;
+ SurfaceMap::iterator i;
+ i = m_surfaces.find(drawSurface); if (i != m_surfaces.end()) draw = i->second->eglSurface();
+ i = m_surfaces.find(readSurface); if (i != m_surfaces.end()) read = i->second->eglSurface();
+
+ return eglMakeCurrent(m_dpy, draw, read, eglContext);
+}
+
+int Renderer::swapBuffers(RenderingThread *thread,
+ const ClientHandle &surface)
+{
+ android::Mutex::Autolock(this->m_mutex);
+
+ SurfaceMap::iterator s = m_surfaces.find(surface);
+ if (s == m_surfaces.end()) {
+ fprintf(stderr, "swapping buffers for non existing surface\n");
+ return -1;
+ }
+ return eglSwapBuffers(m_dpy, s->second->eglSurface());
+}
diff --git a/tools/emulator/opengl/tests/ut_renderer/Renderer.h b/tools/emulator/opengl/tests/ut_renderer/Renderer.h
new file mode 100644
index 0000000..cdf10b6
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/Renderer.h
@@ -0,0 +1,62 @@
+/*
+* 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.
+*/
+#ifndef _RENDERER_H_
+#define _RENDERER_H_
+#include <map>
+#include "RendererSurface.h"
+#include "RendererContext.h"
+#include "NativeWindowing.h"
+#include <utils/threads.h>
+
+class RenderingThread;
+
+class Renderer {
+public:
+
+ class ClientHandle {
+ public:
+ unsigned int pid;
+ unsigned int handle;
+ ClientHandle(unsigned int _pid, unsigned int _handle) : pid(_pid), handle(_handle) {}
+
+ bool operator< (const ClientHandle & p) const {
+ bool val = (pid == p.pid) ? handle < p.handle : pid < p.pid;
+ return val;
+ }
+ };
+
+ static Renderer *instance();
+ int createSurface(RenderingThread *thread, const ClientHandle & handle);
+ int destroySurface(RenderingThread *thread, const ClientHandle &handle);
+ int createContext(RenderingThread *thread, const ClientHandle & ctx, const ClientHandle shareCtx, int version);
+ int destroyContext(RenderingThread *thread,const ClientHandle & ctx);
+ int makeCurrent(RenderingThread *thread,
+ const ClientHandle & drawSurface, const ClientHandle & readSurface, const ClientHandle & ctx);
+ int swapBuffers(RenderingThread *thread, const ClientHandle & surface);
+
+private:
+ typedef std::map<ClientHandle, RendererSurface *> SurfaceMap;
+ typedef std::map<ClientHandle, RendererContext *> ContextMap;
+ static Renderer *m_instance;
+ Renderer();
+ SurfaceMap m_surfaces;
+ ContextMap m_ctxs;
+ NativeWindowing *m_nw;
+ EGLDisplay m_dpy;
+
+ android::Mutex m_mutex; // single global mutex for the renderer class;
+};
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp b/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp
new file mode 100644
index 0000000..0f93acd
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp
@@ -0,0 +1,66 @@
+/*
+* 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.
+*/
+#include "RendererContext.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+RendererContext * RendererContext::create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx, int version)
+{
+ EGLContext ctx;
+ EGLContext shared = shareCtx == NULL ? EGL_NO_CONTEXT : shareCtx->eglContext();
+
+ EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE };
+ context_attributes[1] = version;
+
+ ctx = eglCreateContext(dpy, config, shared, context_attributes);
+ if (eglGetError() != EGL_SUCCESS) return NULL;
+
+ return new RendererContext(dpy, ctx, version);
+}
+
+int RendererContext::destroy()
+{
+ if (count() <= 0) {
+ eglDestroyContext(m_dpy, m_ctx);
+ return 1;
+ }
+ return 0;
+}
+
+#ifdef PVR_WAR
+void RendererContext::setActiveTexture(GLenum texture)
+{
+ m_activeTexture = texture - GL_TEXTURE0;
+}
+
+void RendererContext::setTex2DBind(GLuint texture)
+{
+ m_tex2DBind[m_activeTexture] = texture;
+}
+
+GLuint RendererContext::getTex2DBind()
+{
+ return m_tex2DBind[m_activeTexture];
+}
+
+void RendererContext::addPendingCropRect(const int *rect)
+{
+ PendingCropRect *r = new PendingCropRect;
+ r->texture = m_tex2DBind[m_activeTexture];
+ memcpy(r->rect, rect, 4*sizeof(int));
+ m_pendingCropRects.insert(r);
+}
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererContext.h b/tools/emulator/opengl/tests/ut_renderer/RendererContext.h
new file mode 100644
index 0000000..bb24a2e
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/RendererContext.h
@@ -0,0 +1,127 @@
+/*
+* 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.
+*/
+#ifndef _RENDERER_CONTEXT_H_
+#define _RENDERER_CONTEXT_H_
+
+#include "RendererObject.h"
+#include "GLDecoderContextData.h"
+
+#include <EGL/egl.h>
+#define GL_API
+#define GL_APIENTRY
+#include <GLES/gl.h>
+#include <string.h>
+
+#ifdef PVR_WAR
+#include <set>
+struct PendingCropRect
+{
+ GLuint texture;
+ int rect[4];
+};
+
+typedef std::set<PendingCropRect *> PendingCropRectSet;
+#endif
+
+class RendererContext : public RendererObject {
+public:
+ static RendererContext *create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx, int version);
+ EGLContext eglContext() { return m_ctx; }
+ int destroy();
+ GLDecoderContextData & decoderContextData() { return m_contextData; }
+#ifdef PVR_WAR
+ void setActiveTexture(GLenum texture);
+ GLenum getActiveTexture() { return GL_TEXTURE0 + m_activeTexture; }
+ void setTex2DBind(GLuint texture);
+ void setTex2DEnable(bool enable) {
+ m_tex2DEnable[m_activeTexture] = enable;
+ }
+ bool isTex2DEnable(int texunit) { return m_tex2DEnable[texunit]; }
+ GLuint getTex2DBind();
+ void addPendingCropRect(const int *rect);
+ PendingCropRectSet &getPendingCropRects() { return m_pendingCropRects; }
+
+ void setClientActiveTexture(GLenum texture) { m_clientActiveTexture = texture - GL_TEXTURE0; }
+ GLenum getClientActiveTexture() { return m_clientActiveTexture + GL_TEXTURE0; }
+ void enableClientState(GLenum cap, bool enable) {
+ switch(cap) {
+ case GL_VERTEX_ARRAY:
+ m_clientStateEnable[0] = enable;
+ break;
+ case GL_NORMAL_ARRAY:
+ m_clientStateEnable[1] = enable;
+ break;
+ case GL_COLOR_ARRAY:
+ m_clientStateEnable[2] = enable;
+ break;
+ case GL_POINT_SIZE_ARRAY_OES:
+ m_clientStateEnable[3] = enable;
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ m_clientStateEnable[4 + m_clientActiveTexture] = enable;
+ break;
+ }
+ }
+
+ bool getClientState(GLenum cap, int texUnit) {
+ switch(cap) {
+ case GL_VERTEX_ARRAY:
+ return m_clientStateEnable[0];
+ case GL_NORMAL_ARRAY:
+ return m_clientStateEnable[1];
+ case GL_COLOR_ARRAY:
+ return m_clientStateEnable[2];
+ case GL_POINT_SIZE_ARRAY_OES:
+ return m_clientStateEnable[3];
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ return m_clientStateEnable[4 + texUnit];
+ break;
+ }
+ return false;
+ }
+#endif
+
+private:
+ EGLDisplay m_dpy;
+ EGLContext m_ctx;
+ GLDecoderContextData m_contextData;
+ int m_version;
+
+ RendererContext(EGLDisplay dpy, EGLContext ctx, int version) :
+ m_dpy(dpy),
+ m_ctx(ctx),
+ m_version(version)
+ {
+#ifdef PVR_WAR
+ m_activeTexture = 0;
+ m_clientActiveTexture = 0;
+ memset(m_tex2DBind, 0, 8*sizeof(GLuint));
+ memset(m_tex2DEnable, 0, 8*sizeof(bool));
+ memset(m_clientStateEnable, 0, 16*sizeof(bool));
+#endif
+ }
+
+#ifdef PVR_WAR
+ int m_tex2DBind[8];
+ bool m_tex2DEnable[8];
+ int m_activeTexture;
+ int m_clientActiveTexture;
+ bool m_clientStateEnable[16];
+ PendingCropRectSet m_pendingCropRects;
+#endif
+};
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererObject.h b/tools/emulator/opengl/tests/ut_renderer/RendererObject.h
new file mode 100644
index 0000000..18c89be
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/RendererObject.h
@@ -0,0 +1,29 @@
+/*
+* 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.
+*/
+#ifndef _RENDERER_OBJECT_H_
+#define _RENDERER_OBJECT_H_
+
+class RendererObject {
+public:
+ RendererObject() { m_count = 0; }
+
+ int count() { return m_count; }
+ void ref() { m_count++; }
+ void unref() { m_count--; }
+private:
+ int m_count;
+};
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererSurface.cpp b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.cpp
new file mode 100644
index 0000000..7d8d8c6
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.cpp
@@ -0,0 +1,108 @@
+/*
+* 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.
+*/
+#include "RendererSurface.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "NativeWindowing.h"
+
+#define MAX_ATTRIB 100
+
+
+EGLConfig RendererSurface::getEglConfig(EGLDisplay eglDisplay, SurfaceConfig config)
+{
+ EGLConfig eglConfig;
+ int nConfigs;
+
+ EGLint attrib[MAX_ATTRIB];
+ int pos =0;
+
+ attrib[pos++] = EGL_SURFACE_TYPE; attrib[pos++] = EGL_WINDOW_BIT;
+ if (config & CONFIG_DEPTH) {attrib[pos++] = EGL_DEPTH_SIZE; attrib[pos++] = 1;}
+ attrib[pos++] = EGL_NONE;
+
+ if (!eglChooseConfig(eglDisplay, attrib, &eglConfig, 1, &nConfigs)) {
+ return 0;
+ }
+ /***/
+ int ibuf;
+ if (eglGetConfigAttrib(eglDisplay, eglConfig, EGL_BUFFER_SIZE, &ibuf)) {
+ fprintf(stderr, "EGL COLOR Buffer size: %d\n", ibuf);
+ } else {
+ fprintf(stderr, "eglGetConfigAttrib error: %d\n", eglGetError());
+ }
+ if (eglGetConfigAttrib(eglDisplay, eglConfig, EGL_DEPTH_SIZE, &ibuf)) {
+ fprintf(stderr, "EGL DEPTH Buffer size: %d\n", ibuf);
+ } else {
+ fprintf(stderr, "eglGetConfigAttrib error: %d\n", eglGetError());
+ }
+ /***/
+
+
+ if (nConfigs != 1) {
+ return 0;
+ }
+ return eglConfig;
+}
+
+RendererSurface * RendererSurface::create(EGLDisplay eglDisplay, SurfaceConfig config, NativeWindowing *nw)
+{
+ int width = 0, height = 0;
+ const char* env;
+
+ env = getenv("ANDROID_WINDOW_WIDTH");
+ if (env && *env) {
+ width = atoi(env);
+ }
+ env = getenv("ANDROID_WINDOW_HEIGHT");
+ if (env && *env) {
+ height = atoi(env);
+ }
+ if (width <= 160)
+ width = DEFAULT_WIDTH;
+ if (height <= 160)
+ height = DEFAULT_HEIGHT;
+
+ printf("%s: Using width=%d height=%d\n", __FUNCTION__, width, height);
+
+ EGLConfig eglConfig = getEglConfig(eglDisplay, config);
+ if (eglConfig == 0) {
+ return NULL;
+ }
+
+ NativeWindowType window = nw->createNativeWindow(nw->getNativeDisplay(), width, height);
+ if (window == 0) {
+ return NULL;
+ }
+
+ EGLSurface eglSurface = eglCreateWindowSurface(eglDisplay,
+ eglConfig,
+ window, NULL);
+
+ if (eglGetError() != EGL_SUCCESS) {
+ return NULL;
+ }
+
+ return new RendererSurface(eglDisplay, window, eglSurface, eglConfig);
+}
+
+int RendererSurface::destroy(NativeWindowing *nw)
+{
+ eglDestroySurface(m_eglDisplay, m_eglSurface);
+ nw->destroyNativeWindow(nw->getNativeDisplay(), m_window);
+ return 1;
+}
+
diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererSurface.h b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.h
new file mode 100644
index 0000000..4f6709c
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.h
@@ -0,0 +1,52 @@
+/*
+* 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.
+*/
+#ifndef _RENDERER_SURFACE_H_
+#define _RENDERER_SURFACE_H_
+
+#include <EGL/egl.h>
+#include "NativeWindowing.h"
+#include "RendererObject.h"
+
+#define DEFAULT_HEIGHT 480
+#define DEFAULT_WIDTH 320
+
+class RendererSurface : public RendererObject {
+public:
+ typedef enum { CONFIG_DEPTH = 1 << 0 } SurfaceConfig;
+
+ EGLSurface eglSurface() { return m_eglSurface; }
+ EGLConfig eglConfig() { return m_config; }
+ EGLDisplay eglDisplay() { return m_eglDisplay; }
+
+ static RendererSurface * create(EGLDisplay eglDisplay, SurfaceConfig config, NativeWindowing *nw);
+ static EGLConfig getEglConfig(EGLDisplay eglDisplay, SurfaceConfig config);
+
+ int destroy(NativeWindowing *nw);
+
+private:
+ RendererSurface(EGLDisplay display, NativeWindowType window, EGLSurface surface, EGLConfig config) :
+ m_eglDisplay(display),
+ m_config(config),
+ m_window(window),
+ m_eglSurface(surface)
+ {}
+
+ EGLDisplay m_eglDisplay;
+ EGLConfig m_config;
+ NativeWindowType m_window;
+ EGLSurface m_eglSurface;
+};
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp
new file mode 100644
index 0000000..ddd8405
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp
@@ -0,0 +1,387 @@
+/*
+* 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.
+*/
+#include "RenderingThread.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <pthread.h>
+#include "ReadBuffer.h"
+#include "Renderer.h"
+#include "TimeUtils.h"
+
+#include <GLES/glext.h>
+
+__thread RenderingThread * RenderingThread::m_tls;
+
+#ifdef PVR_WAR
+void RenderingThread::s_glTexParameteriv(GLenum target, GLenum param, const int *p)
+{
+ if (target == GL_TEXTURE_2D && param == GL_TEXTURE_CROP_RECT_OES) {
+ m_tls->m_currentContext->addPendingCropRect(p);
+ } else {
+ m_tls->m_glTexParameteriv(target, param, p);
+ }
+}
+
+void RenderingThread::s_glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexfOES(x, y, z, w, h);
+ m_tls->fixTextureEnable();
+}
+
+void RenderingThread::s_glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort w, GLshort h)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexsOES(x, y, z, w, h);
+ m_tls->fixTextureEnable();
+}
+
+void RenderingThread::s_glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexiOES(x, y, z, w, h);
+ m_tls->fixTextureEnable();
+}
+
+void RenderingThread::s_glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexxOES(x, y, z, w, h);
+ m_tls->fixTextureEnable();
+}
+
+void RenderingThread::s_glDrawTexfvOES(const GLfloat *coords)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexfvOES(coords);
+ m_tls->fixTextureEnable();
+}
+
+void RenderingThread::s_glDrawTexsvOES(const GLshort *coords)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexsvOES(coords);
+ m_tls->fixTextureEnable();
+}
+
+void RenderingThread::s_glDrawTexivOES(const GLint *coords)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexivOES(coords);
+ m_tls->fixTextureEnable();
+}
+
+void RenderingThread::s_glDrawTexxvOES(const GLfixed *coords)
+{
+ m_tls->applyPendingCropRects();
+ m_tls->m_glDrawTexxvOES(coords);
+ m_tls->fixTextureEnable();
+}
+
+
+void RenderingThread::s_glActiveTexture(GLenum texture)
+{
+ if (texture - GL_TEXTURE0 >= m_tls->m_backendCaps.maxTextureUnits) return;
+
+ m_tls->m_currentContext->setActiveTexture(texture);
+ m_tls->m_glActiveTexture(texture);
+}
+
+void RenderingThread::s_glBindTexture(GLenum target, GLuint texture)
+{
+ if (target == GL_TEXTURE_2D) m_tls->m_currentContext->setTex2DBind(texture);
+ m_tls->m_glBindTexture(target, texture);
+}
+
+void RenderingThread::s_glEnable(GLenum cap)
+{
+ if (cap == GL_TEXTURE_2D) m_tls->m_currentContext->setTex2DEnable(true);
+ m_tls->m_glEnable(cap);
+}
+
+void RenderingThread::s_glDisable(GLenum cap)
+{
+ if (cap == GL_TEXTURE_2D) m_tls->m_currentContext->setTex2DEnable(false);
+ m_tls->m_glDisable(cap);
+}
+
+void RenderingThread::s_glClientActiveTexture(GLenum texture)
+{
+ if (texture - GL_TEXTURE0 >= m_tls->m_backendCaps.maxTextureUnits) return;
+ m_tls->m_currentContext->setClientActiveTexture(texture);
+ m_tls->m_glClientActiveTexture(texture);
+}
+
+void RenderingThread::s_glEnableClientState(GLenum cap)
+{
+ m_tls->m_currentContext->enableClientState(cap, true);
+ m_tls->m_glEnableClientState(cap);
+}
+
+void RenderingThread::s_glDisableClientState(GLenum cap)
+{
+ m_tls->m_currentContext->enableClientState(cap, false);
+ m_tls->m_glDisableClientState(cap);
+}
+
+void RenderingThread::applyPendingCropRects()
+{
+ PendingCropRectSet &rset = m_currentContext->getPendingCropRects();
+ if (rset.size() > 0) {
+ GLuint currBindedTex = m_currentContext->getTex2DBind();
+ for (PendingCropRectSet::iterator i = rset.begin();
+ i != rset.end();
+ i++) {
+ m_glBindTexture(GL_TEXTURE_2D, (*i)->texture);
+ m_glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, (int *)(*i)->rect);
+ delete (*i);
+ }
+ m_glBindTexture(GL_TEXTURE_2D, currBindedTex);
+ rset.clear();
+ }
+}
+
+void RenderingThread::fixTextureEnable()
+{
+ // restore texture units enable state
+ for (unsigned int i=0; i<m_backendCaps.maxTextureUnits; i++) {
+ m_glActiveTexture(GL_TEXTURE0 + i);
+ if (m_currentContext->isTex2DEnable(i)) {
+ m_glEnable(GL_TEXTURE_2D);
+ }
+ else {
+ m_glDisable(GL_TEXTURE_2D);
+ }
+ m_glClientActiveTexture(GL_TEXTURE0 + i);
+ if (m_currentContext->getClientState(GL_TEXTURE_COORD_ARRAY, i)) {
+ m_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ else {
+ m_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+ }
+ // restore current active texture
+ m_glActiveTexture(m_currentContext->getActiveTexture());
+ m_glClientActiveTexture(m_currentContext->getClientActiveTexture());
+
+ // restore other client state enable bits
+ if (m_currentContext->getClientState(GL_VERTEX_ARRAY, 0)) {
+ m_glEnableClientState(GL_VERTEX_ARRAY);
+ }
+ else {
+ m_glDisableClientState(GL_VERTEX_ARRAY);
+ }
+
+ if (m_currentContext->getClientState(GL_NORMAL_ARRAY, 0)) {
+ m_glEnableClientState(GL_NORMAL_ARRAY);
+ }
+ else {
+ m_glDisableClientState(GL_NORMAL_ARRAY);
+ }
+
+ if (m_currentContext->getClientState(GL_COLOR_ARRAY, 0)) {
+ m_glEnableClientState(GL_COLOR_ARRAY);
+ }
+ else {
+ m_glDisableClientState(GL_COLOR_ARRAY);
+ }
+
+ if (m_currentContext->getClientState(GL_POINT_SIZE_ARRAY_OES, 0)) {
+ m_glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
+ }
+ else {
+ m_glDisableClientState(GL_POINT_SIZE_ARRAY_OES);
+ }
+}
+#endif
+
+
+int RenderingThread::s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx, int version)
+{
+ return Renderer::instance()->createContext(m_tls, Renderer::ClientHandle(pid, handle),
+ Renderer::ClientHandle(pid, shareCtx),
+ version);
+
+}
+
+
+int RenderingThread::s_createSurface(uint32_t pid, uint32_t handle)
+{
+ return Renderer::instance()->createSurface(m_tls, Renderer::ClientHandle(pid, handle));
+}
+
+int RenderingThread::s_destroySurface(uint32_t pid, uint32_t handle)
+{
+ return Renderer::instance()->destroySurface(m_tls, Renderer::ClientHandle(pid, handle));
+}
+
+int RenderingThread::s_destroyContext(uint32_t pid, uint32_t handle)
+{
+ return Renderer::instance()->destroyContext(m_tls, Renderer::ClientHandle(pid, handle));
+}
+
+
+int RenderingThread::s_makeCurrent(uint32_t pid, uint32_t drawSurface, uint32_t readSurface, uint32_t ctx)
+{
+ int ret = Renderer::instance()->makeCurrent(m_tls,
+ Renderer::ClientHandle(pid, drawSurface),
+ Renderer::ClientHandle(pid, readSurface),
+ Renderer::ClientHandle(pid, ctx));
+
+ if (ret && ctx) {
+ m_tls->initBackendCaps();
+ }
+
+ return ret;
+}
+
+void RenderingThread::s_swapBuffers(uint32_t pid, uint32_t surface)
+{
+ Renderer::instance()->swapBuffers(m_tls, Renderer::ClientHandle(pid, surface));
+}
+
+
+RenderingThread::RenderingThread(TcpStream *stream) :
+ m_stream(stream),
+ m_currentContext(NULL)
+{
+ m_backendCaps.initialized = false;
+}
+
+int RenderingThread::start(void)
+{
+ if (pthread_create(&m_thread, NULL, s_thread, this) < 0) {
+ perror("pthread_create");
+ return -1;
+ }
+ return 0;
+}
+
+
+void * RenderingThread::s_thread(void *data)
+{
+ RenderingThread *self = (RenderingThread *)data;
+ m_tls = self;
+ return self->thread();
+}
+
+void RenderingThread::initBackendCaps()
+{
+ if (m_backendCaps.initialized) return;
+
+ m_glDec.glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint *)&m_backendCaps.maxTextureUnits);
+ m_backendCaps.initialized = true;
+}
+
+void *RenderingThread::thread()
+{
+
+ // initialize our decoders;
+ m_glDec.initGL();
+
+#ifdef PVR_WAR
+ m_glTexParameteriv = m_glDec.set_glTexParameteriv(s_glTexParameteriv);
+ m_glDrawTexfOES = m_glDec.set_glDrawTexfOES(s_glDrawTexfOES);
+ m_glDrawTexsOES = m_glDec.set_glDrawTexsOES(s_glDrawTexsOES);
+ m_glDrawTexiOES = m_glDec.set_glDrawTexiOES(s_glDrawTexiOES);
+ m_glDrawTexxOES = m_glDec.set_glDrawTexxOES(s_glDrawTexxOES);
+ m_glDrawTexfvOES = m_glDec.set_glDrawTexfvOES(s_glDrawTexfvOES);
+ m_glDrawTexsvOES = m_glDec.set_glDrawTexsvOES(s_glDrawTexsvOES);
+ m_glDrawTexivOES = m_glDec.set_glDrawTexivOES(s_glDrawTexivOES);
+ m_glDrawTexxvOES = m_glDec.set_glDrawTexxvOES(s_glDrawTexxvOES);
+ m_glActiveTexture = m_glDec.set_glActiveTexture(s_glActiveTexture);
+ m_glBindTexture = m_glDec.set_glBindTexture(s_glBindTexture);
+ m_glEnable = m_glDec.set_glEnable(s_glEnable);
+ m_glDisable = m_glDec.set_glDisable(s_glDisable);
+ m_glClientActiveTexture = m_glDec.set_glClientActiveTexture(s_glClientActiveTexture);
+ m_glEnableClientState = m_glDec.set_glEnableClientState(s_glEnableClientState);
+ m_glDisableClientState = m_glDec.set_glDisableClientState(s_glDisableClientState);
+#endif
+
+ m_gl2Dec.initGL();
+
+ m_utDec.set_swapBuffers(s_swapBuffers);
+ m_utDec.set_createContext(s_createContext);
+ m_utDec.set_destroyContext(s_destroyContext);
+ m_utDec.set_createSurface(s_createSurface);
+ m_utDec.set_destroySurface(s_destroySurface);
+ m_utDec.set_makeCurrentContext(s_makeCurrent);
+
+ ReadBuffer readBuf(m_stream, DECODER_BUF_SIZE);
+
+ int stats_totalBytes = 0;
+ long long stats_t0 = GetCurrentTimeMS();
+
+ while (1) {
+
+ int stat = readBuf.getData();
+ if (stat == 0) {
+ fprintf(stderr, "client shutdown\n");
+ break;
+ } else if (stat < 0) {
+ perror("getData");
+ break;
+ }
+
+ //
+ // log received bandwidth statistics
+ //
+ stats_totalBytes += readBuf.validData();
+ long long dt = GetCurrentTimeMS() - stats_t0;
+ if (dt > 1000) {
+ float dts = (float)dt / 1000.0f;
+ printf("Used Bandwidth %5.3f MB/s\n", ((float)stats_totalBytes / dts) / (1024.0f*1024.0f));
+ stats_totalBytes = 0;
+ stats_t0 = GetCurrentTimeMS();
+ }
+
+ bool progress = true;
+ while (progress) {
+ progress = false;
+ // we need at least one header (8 bytes) in our buffer
+ if (readBuf.validData() >= 8) {
+ size_t last = m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+ if (last > 0) {
+ progress = true;
+ readBuf.consume(last);
+ }
+ }
+
+ if (readBuf.validData() >= 8) {
+ size_t last = m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+ if (last > 0) {
+ readBuf.consume(last);
+ progress = true;
+ }
+ }
+
+ if (readBuf.validData() >= 8) {
+ size_t last = m_utDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+ if (last > 0) {
+ readBuf.consume(last);
+ progress = true;
+ }
+ }
+ }
+ }
+ // shutdown
+ if (m_currentContext != NULL) {
+ m_currentContext->unref();
+ }
+
+ return NULL;
+}
diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h
new file mode 100644
index 0000000..549d4af
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h
@@ -0,0 +1,117 @@
+/*
+* 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.
+*/
+#ifndef _RENDERING_THREAD_H_
+#define _RENDERING_THREAD_H_
+
+#include "TcpStream.h"
+#include "GLDecoder.h"
+#include "GL2Decoder.h"
+#include "ut_rendercontrol_dec.h"
+#include <pthread.h>
+
+#define GL_API
+#define GL_APIENTRY
+
+#include <GLES/egl.h>
+#include <GLES/gl.h>
+
+
+#define WINDOW_WIDTH 320
+#define WINDOW_HEIGHT 480
+
+#define DECODER_BUF_SIZE (4 * 1024 * 1024)
+
+class RendererContext;
+
+class RenderingThread {
+public:
+ RenderingThread(TcpStream *stream);
+ int start();
+ void *thread();
+ RendererContext *currentContext() { return m_currentContext; }
+ void setCurrentContext(RendererContext *ctx) { m_currentContext = ctx; }
+ GLDecoder & glDecoder() { return m_glDec; }
+ GL2Decoder & gl2Decoder() { return m_gl2Dec; }
+
+private:
+ void initBackendCaps();
+
+private:
+ GLDecoder m_glDec;
+ ut_rendercontrol_decoder_context_t m_utDec;
+ GL2Decoder m_gl2Dec;
+
+ TcpStream *m_stream;
+ pthread_t m_thread;
+ RendererContext * m_currentContext;
+
+ struct BackendCaps {
+ bool initialized;
+ GLuint maxTextureUnits;
+ } m_backendCaps;
+
+ static void * s_thread(void *data);
+ static __thread RenderingThread *m_tls;
+
+ static int s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx, int version);
+ static int s_createSurface(uint32_t pid, uint32_t handle);
+ static int s_destroySurface(uint32_t pid, uint32_t handle);
+ static int s_destroyContext(uint32_t pid, uint32_t handle);
+ static int s_makeCurrent(uint32_t pid, uint32_t drawSurface, uint32_t readSurface, uint32_t ctx);
+ static void s_swapBuffers(uint32_t pid, uint32_t surface);
+#ifdef PVR_WAR
+ static void s_glTexParameteriv(GLenum target, GLenum param, const int *p);
+ static void s_glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h);
+ static void s_glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort w, GLshort h);
+ static void s_glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h);
+ static void s_glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h);
+ static void s_glDrawTexfvOES(const GLfloat *coords);
+ static void s_glDrawTexsvOES(const GLshort *coords);
+ static void s_glDrawTexivOES(const GLint *coords);
+ static void s_glDrawTexxvOES(const GLfixed *coords);
+
+ static void s_glActiveTexture(GLenum texture);
+ static void s_glBindTexture(GLenum target, GLuint texture);
+ static void s_glEnable(GLenum cap);
+ static void s_glDisable(GLenum cap);
+ static void s_glClientActiveTexture(GLenum texture);
+ static void s_glEnableClientState(GLenum cap);
+ static void s_glDisableClientState(GLenum cap);
+
+ void applyPendingCropRects();
+ void fixTextureEnable();
+
+ glTexParameteriv_server_proc_t m_glTexParameteriv;
+ glDrawTexfOES_server_proc_t m_glDrawTexfOES;
+ glDrawTexiOES_server_proc_t m_glDrawTexiOES;
+ glDrawTexsOES_server_proc_t m_glDrawTexsOES;
+ glDrawTexxOES_server_proc_t m_glDrawTexxOES;
+ glDrawTexfvOES_server_proc_t m_glDrawTexfvOES;
+ glDrawTexivOES_server_proc_t m_glDrawTexivOES;
+ glDrawTexsvOES_server_proc_t m_glDrawTexsvOES;
+ glDrawTexxvOES_server_proc_t m_glDrawTexxvOES;
+ glActiveTexture_server_proc_t m_glActiveTexture;
+ glBindTexture_server_proc_t m_glBindTexture;
+ glEnable_server_proc_t m_glEnable;
+ glDisable_server_proc_t m_glDisable;
+ glClientActiveTexture_server_proc_t m_glClientActiveTexture;
+ glEnableClientState_server_proc_t m_glEnableClientState;
+ glDisableClientState_server_proc_t m_glDisableClientState;
+#endif
+
+};
+
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.cpp b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.cpp
new file mode 100644
index 0000000..121ee87
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.cpp
@@ -0,0 +1,69 @@
+/*
+* 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.
+*/
+#include "X11RendererSurface.h"
+
+NativeDisplayType X11RendererSurface::getNativeDisplay()
+{
+ if (m_display == NULL) {
+ m_display = XOpenDisplay(NULL);
+ }
+ return NativeDisplayType(m_display);
+}
+
+int X11RendererSurface::destoryNativeWindow(NativeWindowType win)
+{
+ if (m_display == NULL) return -1;
+
+ Window x11Window = (Window)(win);
+ return XDestroyWindow(m_display, x11Window);
+}
+
+NativeWindowType GlesX11Win::createNativeWindow()
+{
+
+ getNativeDisplay();
+ if (m_display == NULL) {
+ return -1;
+ }
+
+ long defaultScreen = DefaultScreen( dpy );
+ Window rootWindow = RootWindow(dpy, defaultScreen);
+ int depth = DefaultDepth(dpy, defaultScreen);
+ XVisualInfo *visualInfo = new XVisualInfo;
+
+ XMatchVisualInfo(m_display, defaultScreen, , dpeth, TrueColor, visualInfo);
+ if (visualInfo == NULL) {
+ fprintf(stderr, "couldn't find matching visual\n");
+ return -1;
+ }
+
+ Colormap x11Colormap = XCreateColormap(m_display, rootWindow, visualInfo->visual, AllocNone);
+ XSetWindowAttributes sWA;
+ sWA.Colormap = x11Colormap;
+ sWA.event_mask = StructureNotifyMask | ExposureMask;
+ unsigned int eventMask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
+
+ Window win = XCreateWindow( m_display,
+ rootWindow,
+ 0, 0, width, height,
+ 0, CopyFromParent, InputOutput,
+ CopyFromParent, eventMask, &sWA);
+
+ XMapWindow(m_display, win);
+ XFlush(m_display);
+ return NativeWindowType(win);
+}
+
diff --git a/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.h b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.h
new file mode 100644
index 0000000..be9bcec
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.h
@@ -0,0 +1,37 @@
+/*
+* 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.
+*/
+#ifndef _X11_RENDERER_SURFACE_H_
+#define _X11_RENDERER_SURFACE_H_
+
+#include <X11/Xutil.h>
+#include <X11/Xlib.h>
+#include <EGL/egl.h>
+
+include "RendererSurface.h"
+
+class X11RendererSurface : public RendererSurface
+{
+public:
+ X11RendererSurface() : RendererSurface() {
+ m_display = NULL;
+ }
+ NativeDisplayType getNativeDisplay();
+ NativeWindowType createNativeWindow();
+ int destroyNativeWindow(NativeWindowType win);
+private:
+ Display m_display;
+};
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/X11Windowing.cpp b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.cpp
new file mode 100644
index 0000000..cc94fdd
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.cpp
@@ -0,0 +1,131 @@
+/*
+* 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.
+*/
+#include "X11Windowing.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#define DEBUG 0
+#if DEBUG
+# define D(...) printf(__VA_ARGS__), printf("\n")
+#else
+# define D(...) ((void)0)
+#endif
+
+/* Try to remember the window position between creates/destroys */
+static int X11_wmXPos = 100;
+static int X11_wmYPos = 100;
+
+static int X11_wmXAdjust = 0;
+static int X11_wmYAdjust = 0;
+
+static void
+get_window_pos( Display *disp, Window win, int *px, int *py )
+{
+ Window child;
+
+ XTranslateCoordinates( disp, win, DefaultRootWindow(disp), 0, 0, px, py, &child );
+}
+
+
+static void
+set_window_pos(Display *disp, Window win, int x, int y)
+{
+ int xNew, yNew;
+ int xAdjust = X11_wmXAdjust;
+ int yAdjust = X11_wmYAdjust;
+
+ /* this code is tricky because some window managers, but not all,
+ * will translate the final window position by a given offset
+ * corresponding to the frame decoration.
+ *
+ * so we first try to move the window, get the position that the
+ * window manager has set, and if they are different, re-position the
+ * window again with an adjustment.
+ *
+ * this causes a slight flicker since the window 'jumps' very
+ * quickly from one position to the other.
+ */
+
+ D("%s: move to [%d,%d] adjusted to [%d,%d]", __FUNCTION__,
+ x, y, x+xAdjust, y+yAdjust);
+ XMoveWindow(disp, win, x + xAdjust, y + yAdjust);
+ XSync(disp, True);
+ get_window_pos(disp, win, &xNew, &yNew);
+ if (xNew != x || yNew != y) {
+ X11_wmXAdjust = xAdjust = x - xNew;
+ X11_wmYAdjust = yAdjust = y - yNew;
+ D("%s: read pos [%d,%d], recomputing adjust=[%d,%d] moving to [%d,%d]\n",
+ __FUNCTION__, xNew, yNew, xAdjust, yAdjust, x+xAdjust, y+yAdjust);
+ XMoveWindow(disp, win, x + xAdjust, y + yAdjust );
+ }
+ XSync(disp, False);
+}
+
+
+NativeDisplayType X11Windowing::getNativeDisplay()
+{
+ Display *dpy = XOpenDisplay(NULL);
+ return (NativeDisplayType)dpy;
+}
+
+NativeWindowType X11Windowing::createNativeWindow(NativeDisplayType _dpy, int width, int height)
+{
+ Display *dpy = (Display *) _dpy;
+
+ long defaultScreen = DefaultScreen( dpy );
+ Window rootWindow = RootWindow(dpy, defaultScreen);
+ int depth = DefaultDepth(dpy, defaultScreen);
+ XVisualInfo *visualInfo = new XVisualInfo;
+
+ XMatchVisualInfo(dpy, defaultScreen, depth, TrueColor, visualInfo);
+ if (visualInfo == NULL) {
+ fprintf(stderr, "couldn't find matching visual\n");
+ return NULL;
+ }
+
+ Colormap x11Colormap = XCreateColormap(dpy, rootWindow, visualInfo->visual, AllocNone);
+ XSetWindowAttributes sWA;
+ sWA.colormap = x11Colormap;
+ sWA.event_mask = StructureNotifyMask | ExposureMask;
+ sWA.background_pixel = 0;
+ sWA.border_pixel = 0;
+ unsigned int attributes_mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
+
+ Window win = XCreateWindow( dpy,
+ rootWindow,
+ X11_wmXPos, X11_wmYPos, width, height,
+ 0, CopyFromParent, InputOutput,
+ CopyFromParent, attributes_mask, &sWA);
+
+ XMapWindow(dpy, win);
+ XFlush(dpy);
+ set_window_pos(dpy, win, X11_wmXPos, X11_wmYPos);
+ return NativeWindowType(win);
+}
+
+int X11Windowing::destroyNativeWindow(NativeDisplayType _dpy, NativeWindowType _win)
+{
+ Display *dpy = (Display *)_dpy;
+ Window win = (Window)_win;
+ get_window_pos(dpy, win, &X11_wmXPos, &X11_wmYPos);
+ D("%s: Saved window position [%d, %d]\n", __FUNCTION__, X11_wmXPos, X11_wmYPos);
+ XDestroyWindow(dpy, win);
+ XFlush(dpy);
+ return 0;
+}
diff --git a/tools/emulator/opengl/tests/ut_renderer/X11Windowing.h b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.h
new file mode 100644
index 0000000..0f0c76b
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.h
@@ -0,0 +1,27 @@
+/*
+* 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.
+*/
+#ifndef _X11WINDOWING_H_
+#define _X11WINDOWING_H_
+
+#include "NativeWindowing.h"
+
+class X11Windowing : public NativeWindowing {
+ NativeDisplayType getNativeDisplay();
+ NativeWindowType createNativeWindow(NativeDisplayType _dpy, int width, int height);
+ int destroyNativeWindow(NativeDisplayType dpy, NativeWindowType win);
+};
+
+#endif
diff --git a/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp b/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp
new file mode 100644
index 0000000..2137a82
--- /dev/null
+++ b/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp
@@ -0,0 +1,52 @@
+/*
+* 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.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "codec_defs.h"
+#include "RenderingThread.h"
+#include "TcpStream.h"
+
+
+int main(int argc, char **argv)
+{
+
+ TcpStream *socket = new TcpStream;
+
+ if (socket->listen(CODEC_SERVER_PORT) < 0) {
+ perror("listen");
+ exit(1);
+ }
+
+ printf("waiting for client connection on port: %d\n", CODEC_SERVER_PORT);
+ while (1) {
+ // wait for client connection
+ TcpStream *glStream = socket->accept();
+ if (glStream == NULL) {
+ printf("failed to get client.. aborting\n");
+ exit(3);
+ }
+ printf("Got client connection, creating a rendering thread;\n");
+ // create a thread to handle this connection
+ RenderingThread *rt = new RenderingThread(glStream);
+ rt->start();
+ }
+
+ return 0;
+}
+
+
diff --git a/tools/emulator/system/gps/Android.mk b/tools/emulator/system/gps/Android.mk
new file mode 100644
index 0000000..41bdc64
--- /dev/null
+++ b/tools/emulator/system/gps/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2010 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.
+
+
+# We're moving the emulator-specific platform libs to
+# development.git/tools/emulator/. The following test is to ensure
+# smooth builds even if the tree contains both versions.
+#
+ifndef BUILD_EMULATOR_GPS_MODULE
+BUILD_EMULATOR_GPS_MODULE := true
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(TARGET_PRODUCT),sim)
+# HAL module implemenation, not prelinked and stored in
+# hw/<GPS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_CFLAGS += -DQEMU_HARDWARE
+LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware
+LOCAL_SRC_FILES := gps_qemu.c
+LOCAL_MODULE := gps.goldfish
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_SHARED_LIBRARY)
+endif
+
+endif # BUILD_EMULATOR_GPS_MODULE
diff --git a/tools/emulator/system/gps/gps_qemu.c b/tools/emulator/system/gps/gps_qemu.c
new file mode 100644
index 0000000..a4699d3
--- /dev/null
+++ b/tools/emulator/system/gps/gps_qemu.c
@@ -0,0 +1,941 @@
+/*
+ * Copyright (C) 2010 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 implements a GPS hardware library for the Android emulator.
+ * the following code should be built as a shared library that will be
+ * placed into /system/lib/hw/gps.goldfish.so
+ *
+ * it will be loaded by the code in hardware/libhardware/hardware.c
+ * which is itself called from android_location_GpsLocationProvider.cpp
+ */
+
+
+#include <errno.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <math.h>
+#include <time.h>
+
+#define LOG_TAG "gps_qemu"
+#include <cutils/log.h>
+#include <cutils/sockets.h>
+#include <hardware/gps.h>
+#include <hardware/qemud.h>
+
+/* the name of the qemud-controlled socket */
+#define QEMU_CHANNEL_NAME "gps"
+
+#define GPS_DEBUG 0
+
+#if GPS_DEBUG
+# define D(...) LOGD(__VA_ARGS__)
+#else
+# define D(...) ((void)0)
+#endif
+
+/*****************************************************************/
+/*****************************************************************/
+/***** *****/
+/***** N M E A T O K E N I Z E R *****/
+/***** *****/
+/*****************************************************************/
+/*****************************************************************/
+
+typedef struct {
+ const char* p;
+ const char* end;
+} Token;
+
+#define MAX_NMEA_TOKENS 16
+
+typedef struct {
+ int count;
+ Token tokens[ MAX_NMEA_TOKENS ];
+} NmeaTokenizer;
+
+static int
+nmea_tokenizer_init( NmeaTokenizer* t, const char* p, const char* end )
+{
+ int count = 0;
+ char* q;
+
+ // the initial '$' is optional
+ if (p < end && p[0] == '$')
+ p += 1;
+
+ // remove trailing newline
+ if (end > p && end[-1] == '\n') {
+ end -= 1;
+ if (end > p && end[-1] == '\r')
+ end -= 1;
+ }
+
+ // get rid of checksum at the end of the sentecne
+ if (end >= p+3 && end[-3] == '*') {
+ end -= 3;
+ }
+
+ while (p < end) {
+ const char* q = p;
+
+ q = memchr(p, ',', end-p);
+ if (q == NULL)
+ q = end;
+
+ if (q > p) {
+ if (count < MAX_NMEA_TOKENS) {
+ t->tokens[count].p = p;
+ t->tokens[count].end = q;
+ count += 1;
+ }
+ }
+ if (q < end)
+ q += 1;
+
+ p = q;
+ }
+
+ t->count = count;
+ return count;
+}
+
+static Token
+nmea_tokenizer_get( NmeaTokenizer* t, int index )
+{
+ Token tok;
+ static const char* dummy = "";
+
+ if (index < 0 || index >= t->count) {
+ tok.p = tok.end = dummy;
+ } else
+ tok = t->tokens[index];
+
+ return tok;
+}
+
+
+static int
+str2int( const char* p, const char* end )
+{
+ int result = 0;
+ int len = end - p;
+
+ for ( ; len > 0; len--, p++ )
+ {
+ int c;
+
+ if (p >= end)
+ goto Fail;
+
+ c = *p - '0';
+ if ((unsigned)c >= 10)
+ goto Fail;
+
+ result = result*10 + c;
+ }
+ return result;
+
+Fail:
+ return -1;
+}
+
+static double
+str2float( const char* p, const char* end )
+{
+ int result = 0;
+ int len = end - p;
+ char temp[16];
+
+ if (len >= (int)sizeof(temp))
+ return 0.;
+
+ memcpy( temp, p, len );
+ temp[len] = 0;
+ return strtod( temp, NULL );
+}
+
+/*****************************************************************/
+/*****************************************************************/
+/***** *****/
+/***** N M E A P A R S E R *****/
+/***** *****/
+/*****************************************************************/
+/*****************************************************************/
+
+#define NMEA_MAX_SIZE 83
+
+typedef struct {
+ int pos;
+ int overflow;
+ int utc_year;
+ int utc_mon;
+ int utc_day;
+ int utc_diff;
+ GpsLocation fix;
+ gps_location_callback callback;
+ char in[ NMEA_MAX_SIZE+1 ];
+} NmeaReader;
+
+
+static void
+nmea_reader_update_utc_diff( NmeaReader* r )
+{
+ time_t now = time(NULL);
+ struct tm tm_local;
+ struct tm tm_utc;
+ long time_local, time_utc;
+
+ gmtime_r( &now, &tm_utc );
+ localtime_r( &now, &tm_local );
+
+ time_local = tm_local.tm_sec +
+ 60*(tm_local.tm_min +
+ 60*(tm_local.tm_hour +
+ 24*(tm_local.tm_yday +
+ 365*tm_local.tm_year)));
+
+ time_utc = tm_utc.tm_sec +
+ 60*(tm_utc.tm_min +
+ 60*(tm_utc.tm_hour +
+ 24*(tm_utc.tm_yday +
+ 365*tm_utc.tm_year)));
+
+ r->utc_diff = time_utc - time_local;
+}
+
+
+static void
+nmea_reader_init( NmeaReader* r )
+{
+ memset( r, 0, sizeof(*r) );
+
+ r->pos = 0;
+ r->overflow = 0;
+ r->utc_year = -1;
+ r->utc_mon = -1;
+ r->utc_day = -1;
+ r->callback = NULL;
+ r->fix.size = sizeof(r->fix);
+
+ nmea_reader_update_utc_diff( r );
+}
+
+
+static void
+nmea_reader_set_callback( NmeaReader* r, gps_location_callback cb )
+{
+ r->callback = cb;
+ if (cb != NULL && r->fix.flags != 0) {
+ D("%s: sending latest fix to new callback", __FUNCTION__);
+ r->callback( &r->fix );
+ r->fix.flags = 0;
+ }
+}
+
+
+static int
+nmea_reader_update_time( NmeaReader* r, Token tok )
+{
+ int hour, minute;
+ double seconds;
+ struct tm tm;
+ time_t fix_time;
+
+ if (tok.p + 6 > tok.end)
+ return -1;
+
+ if (r->utc_year < 0) {
+ // no date yet, get current one
+ time_t now = time(NULL);
+ gmtime_r( &now, &tm );
+ r->utc_year = tm.tm_year + 1900;
+ r->utc_mon = tm.tm_mon + 1;
+ r->utc_day = tm.tm_mday;
+ }
+
+ hour = str2int(tok.p, tok.p+2);
+ minute = str2int(tok.p+2, tok.p+4);
+ seconds = str2float(tok.p+4, tok.end);
+
+ tm.tm_hour = hour;
+ tm.tm_min = minute;
+ tm.tm_sec = (int) seconds;
+ tm.tm_year = r->utc_year - 1900;
+ tm.tm_mon = r->utc_mon - 1;
+ tm.tm_mday = r->utc_day;
+ tm.tm_isdst = -1;
+
+ fix_time = mktime( &tm ) + r->utc_diff;
+ r->fix.timestamp = (long long)fix_time * 1000;
+ return 0;
+}
+
+static int
+nmea_reader_update_date( NmeaReader* r, Token date, Token time )
+{
+ Token tok = date;
+ int day, mon, year;
+
+ if (tok.p + 6 != tok.end) {
+ D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
+ return -1;
+ }
+ day = str2int(tok.p, tok.p+2);
+ mon = str2int(tok.p+2, tok.p+4);
+ year = str2int(tok.p+4, tok.p+6) + 2000;
+
+ if ((day|mon|year) < 0) {
+ D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
+ return -1;
+ }
+
+ r->utc_year = year;
+ r->utc_mon = mon;
+ r->utc_day = day;
+
+ return nmea_reader_update_time( r, time );
+}
+
+
+static double
+convert_from_hhmm( Token tok )
+{
+ double val = str2float(tok.p, tok.end);
+ int degrees = (int)(floor(val) / 100);
+ double minutes = val - degrees*100.;
+ double dcoord = degrees + minutes / 60.0;
+ return dcoord;
+}
+
+
+static int
+nmea_reader_update_latlong( NmeaReader* r,
+ Token latitude,
+ char latitudeHemi,
+ Token longitude,
+ char longitudeHemi )
+{
+ double lat, lon;
+ Token tok;
+
+ tok = latitude;
+ if (tok.p + 6 > tok.end) {
+ D("latitude is too short: '%.*s'", tok.end-tok.p, tok.p);
+ return -1;
+ }
+ lat = convert_from_hhmm(tok);
+ if (latitudeHemi == 'S')
+ lat = -lat;
+
+ tok = longitude;
+ if (tok.p + 6 > tok.end) {
+ D("longitude is too short: '%.*s'", tok.end-tok.p, tok.p);
+ return -1;
+ }
+ lon = convert_from_hhmm(tok);
+ if (longitudeHemi == 'W')
+ lon = -lon;
+
+ r->fix.flags |= GPS_LOCATION_HAS_LAT_LONG;
+ r->fix.latitude = lat;
+ r->fix.longitude = lon;
+ return 0;
+}
+
+
+static int
+nmea_reader_update_altitude( NmeaReader* r,
+ Token altitude,
+ Token units )
+{
+ double alt;
+ Token tok = altitude;
+
+ if (tok.p >= tok.end)
+ return -1;
+
+ r->fix.flags |= GPS_LOCATION_HAS_ALTITUDE;
+ r->fix.altitude = str2float(tok.p, tok.end);
+ return 0;
+}
+
+
+static int
+nmea_reader_update_bearing( NmeaReader* r,
+ Token bearing )
+{
+ double alt;
+ Token tok = bearing;
+
+ if (tok.p >= tok.end)
+ return -1;
+
+ r->fix.flags |= GPS_LOCATION_HAS_BEARING;
+ r->fix.bearing = str2float(tok.p, tok.end);
+ return 0;
+}
+
+
+static int
+nmea_reader_update_speed( NmeaReader* r,
+ Token speed )
+{
+ double alt;
+ Token tok = speed;
+
+ if (tok.p >= tok.end)
+ return -1;
+
+ r->fix.flags |= GPS_LOCATION_HAS_SPEED;
+ r->fix.speed = str2float(tok.p, tok.end);
+ return 0;
+}
+
+
+static void
+nmea_reader_parse( NmeaReader* r )
+{
+ /* we received a complete sentence, now parse it to generate
+ * a new GPS fix...
+ */
+ NmeaTokenizer tzer[1];
+ Token tok;
+
+ D("Received: '%.*s'", r->pos, r->in);
+ if (r->pos < 9) {
+ D("Too short. discarded.");
+ return;
+ }
+
+ nmea_tokenizer_init(tzer, r->in, r->in + r->pos);
+#if GPS_DEBUG
+ {
+ int n;
+ D("Found %d tokens", tzer->count);
+ for (n = 0; n < tzer->count; n++) {
+ Token tok = nmea_tokenizer_get(tzer,n);
+ D("%2d: '%.*s'", n, tok.end-tok.p, tok.p);
+ }
+ }
+#endif
+
+ tok = nmea_tokenizer_get(tzer, 0);
+ if (tok.p + 5 > tok.end) {
+ D("sentence id '%.*s' too short, ignored.", tok.end-tok.p, tok.p);
+ return;
+ }
+
+ // ignore first two characters.
+ tok.p += 2;
+ if ( !memcmp(tok.p, "GGA", 3) ) {
+ // GPS fix
+ Token tok_time = nmea_tokenizer_get(tzer,1);
+ Token tok_latitude = nmea_tokenizer_get(tzer,2);
+ Token tok_latitudeHemi = nmea_tokenizer_get(tzer,3);
+ Token tok_longitude = nmea_tokenizer_get(tzer,4);
+ Token tok_longitudeHemi = nmea_tokenizer_get(tzer,5);
+ Token tok_altitude = nmea_tokenizer_get(tzer,9);
+ Token tok_altitudeUnits = nmea_tokenizer_get(tzer,10);
+
+ nmea_reader_update_time(r, tok_time);
+ nmea_reader_update_latlong(r, tok_latitude,
+ tok_latitudeHemi.p[0],
+ tok_longitude,
+ tok_longitudeHemi.p[0]);
+ nmea_reader_update_altitude(r, tok_altitude, tok_altitudeUnits);
+
+ } else if ( !memcmp(tok.p, "GSA", 3) ) {
+ // do something ?
+ } else if ( !memcmp(tok.p, "RMC", 3) ) {
+ Token tok_time = nmea_tokenizer_get(tzer,1);
+ Token tok_fixStatus = nmea_tokenizer_get(tzer,2);
+ Token tok_latitude = nmea_tokenizer_get(tzer,3);
+ Token tok_latitudeHemi = nmea_tokenizer_get(tzer,4);
+ Token tok_longitude = nmea_tokenizer_get(tzer,5);
+ Token tok_longitudeHemi = nmea_tokenizer_get(tzer,6);
+ Token tok_speed = nmea_tokenizer_get(tzer,7);
+ Token tok_bearing = nmea_tokenizer_get(tzer,8);
+ Token tok_date = nmea_tokenizer_get(tzer,9);
+
+ D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);
+ if (tok_fixStatus.p[0] == 'A')
+ {
+ nmea_reader_update_date( r, tok_date, tok_time );
+
+ nmea_reader_update_latlong( r, tok_latitude,
+ tok_latitudeHemi.p[0],
+ tok_longitude,
+ tok_longitudeHemi.p[0] );
+
+ nmea_reader_update_bearing( r, tok_bearing );
+ nmea_reader_update_speed ( r, tok_speed );
+ }
+ } else {
+ tok.p -= 2;
+ D("unknown sentence '%.*s", tok.end-tok.p, tok.p);
+ }
+ if (r->fix.flags != 0) {
+#if GPS_DEBUG
+ char temp[256];
+ char* p = temp;
+ char* end = p + sizeof(temp);
+ struct tm utc;
+
+ p += snprintf( p, end-p, "sending fix" );
+ if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {
+ p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);
+ }
+ if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {
+ p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);
+ }
+ if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {
+ p += snprintf(p, end-p, " speed=%g", r->fix.speed);
+ }
+ if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {
+ p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);
+ }
+ if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {
+ p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);
+ }
+ gmtime_r( (time_t*) &r->fix.timestamp, &utc );
+ p += snprintf(p, end-p, " time=%s", asctime( &utc ) );
+ D(temp);
+#endif
+ if (r->callback) {
+ r->callback( &r->fix );
+ r->fix.flags = 0;
+ }
+ else {
+ D("no callback, keeping data until needed !");
+ }
+ }
+}
+
+
+static void
+nmea_reader_addc( NmeaReader* r, int c )
+{
+ if (r->overflow) {
+ r->overflow = (c != '\n');
+ return;
+ }
+
+ if (r->pos >= (int) sizeof(r->in)-1 ) {
+ r->overflow = 1;
+ r->pos = 0;
+ return;
+ }
+
+ r->in[r->pos] = (char)c;
+ r->pos += 1;
+
+ if (c == '\n') {
+ nmea_reader_parse( r );
+ r->pos = 0;
+ }
+}
+
+
+/*****************************************************************/
+/*****************************************************************/
+/***** *****/
+/***** C O N N E C T I O N S T A T E *****/
+/***** *****/
+/*****************************************************************/
+/*****************************************************************/
+
+/* commands sent to the gps thread */
+enum {
+ CMD_QUIT = 0,
+ CMD_START = 1,
+ CMD_STOP = 2
+};
+
+
+/* this is the state of our connection to the qemu_gpsd daemon */
+typedef struct {
+ int init;
+ int fd;
+ GpsCallbacks callbacks;
+ pthread_t thread;
+ int control[2];
+} GpsState;
+
+static GpsState _gps_state[1];
+
+
+static void
+gps_state_done( GpsState* s )
+{
+ // tell the thread to quit, and wait for it
+ char cmd = CMD_QUIT;
+ void* dummy;
+ write( s->control[0], &cmd, 1 );
+ pthread_join(s->thread, &dummy);
+
+ // close the control socket pair
+ close( s->control[0] ); s->control[0] = -1;
+ close( s->control[1] ); s->control[1] = -1;
+
+ // close connection to the QEMU GPS daemon
+ close( s->fd ); s->fd = -1;
+ s->init = 0;
+}
+
+
+static void
+gps_state_start( GpsState* s )
+{
+ char cmd = CMD_START;
+ int ret;
+
+ do { ret=write( s->control[0], &cmd, 1 ); }
+ while (ret < 0 && errno == EINTR);
+
+ if (ret != 1)
+ D("%s: could not send CMD_START command: ret=%d: %s",
+ __FUNCTION__, ret, strerror(errno));
+}
+
+
+static void
+gps_state_stop( GpsState* s )
+{
+ char cmd = CMD_STOP;
+ int ret;
+
+ do { ret=write( s->control[0], &cmd, 1 ); }
+ while (ret < 0 && errno == EINTR);
+
+ if (ret != 1)
+ D("%s: could not send CMD_STOP command: ret=%d: %s",
+ __FUNCTION__, ret, strerror(errno));
+}
+
+
+static int
+epoll_register( int epoll_fd, int fd )
+{
+ struct epoll_event ev;
+ int ret, flags;
+
+ /* important: make the fd non-blocking */
+ flags = fcntl(fd, F_GETFL);
+ fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+
+ ev.events = EPOLLIN;
+ ev.data.fd = fd;
+ do {
+ ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );
+ } while (ret < 0 && errno == EINTR);
+ return ret;
+}
+
+
+static int
+epoll_deregister( int epoll_fd, int fd )
+{
+ int ret;
+ do {
+ ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );
+ } while (ret < 0 && errno == EINTR);
+ return ret;
+}
+
+/* this is the main thread, it waits for commands from gps_state_start/stop and,
+ * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences
+ * that must be parsed to be converted into GPS fixes sent to the framework
+ */
+static void
+gps_state_thread( void* arg )
+{
+ GpsState* state = (GpsState*) arg;
+ NmeaReader reader[1];
+ int epoll_fd = epoll_create(2);
+ int started = 0;
+ int gps_fd = state->fd;
+ int control_fd = state->control[1];
+
+ nmea_reader_init( reader );
+
+ // register control file descriptors for polling
+ epoll_register( epoll_fd, control_fd );
+ epoll_register( epoll_fd, gps_fd );
+
+ D("gps thread running");
+
+ // now loop
+ for (;;) {
+ struct epoll_event events[2];
+ int ne, nevents;
+
+ nevents = epoll_wait( epoll_fd, events, 2, -1 );
+ if (nevents < 0) {
+ if (errno != EINTR)
+ LOGE("epoll_wait() unexpected error: %s", strerror(errno));
+ continue;
+ }
+ D("gps thread received %d events", nevents);
+ for (ne = 0; ne < nevents; ne++) {
+ if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != 0) {
+ LOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");
+ return;
+ }
+ if ((events[ne].events & EPOLLIN) != 0) {
+ int fd = events[ne].data.fd;
+
+ if (fd == control_fd)
+ {
+ char cmd = 255;
+ int ret;
+ D("gps control fd event");
+ do {
+ ret = read( fd, &cmd, 1 );
+ } while (ret < 0 && errno == EINTR);
+
+ if (cmd == CMD_QUIT) {
+ D("gps thread quitting on demand");
+ return;
+ }
+ else if (cmd == CMD_START) {
+ if (!started) {
+ D("gps thread starting location_cb=%p", state->callbacks.location_cb);
+ started = 1;
+ nmea_reader_set_callback( reader, state->callbacks.location_cb );
+ }
+ }
+ else if (cmd == CMD_STOP) {
+ if (started) {
+ D("gps thread stopping");
+ started = 0;
+ nmea_reader_set_callback( reader, NULL );
+ }
+ }
+ }
+ else if (fd == gps_fd)
+ {
+ char buff[32];
+ D("gps fd event");
+ for (;;) {
+ int nn, ret;
+
+ ret = read( fd, buff, sizeof(buff) );
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ if (errno != EWOULDBLOCK)
+ LOGE("error while reading from gps daemon socket: %s:", strerror(errno));
+ break;
+ }
+ D("received %d bytes: %.*s", ret, ret, buff);
+ for (nn = 0; nn < ret; nn++)
+ nmea_reader_addc( reader, buff[nn] );
+ }
+ D("gps fd event end");
+ }
+ else
+ {
+ LOGE("epoll_wait() returned unkown fd %d ?", fd);
+ }
+ }
+ }
+ }
+}
+
+
+static void
+gps_state_init( GpsState* state, GpsCallbacks* callbacks )
+{
+ state->init = 1;
+ state->control[0] = -1;
+ state->control[1] = -1;
+ state->fd = -1;
+
+ state->fd = qemud_channel_open(QEMU_CHANNEL_NAME);
+
+ if (state->fd < 0) {
+ D("no gps emulation detected");
+ return;
+ }
+
+ D("gps emulation will read from '%s' qemud channel", QEMU_CHANNEL_NAME );
+
+ if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) {
+ LOGE("could not create thread control socket pair: %s", strerror(errno));
+ goto Fail;
+ }
+
+ state->thread = callbacks->create_thread_cb( "gps_state_thread", gps_state_thread, state );
+
+ if ( !state->thread ) {
+ LOGE("could not create gps thread: %s", strerror(errno));
+ goto Fail;
+ }
+
+ state->callbacks = *callbacks;
+
+ D("gps state initialized");
+ return;
+
+Fail:
+ gps_state_done( state );
+}
+
+
+/*****************************************************************/
+/*****************************************************************/
+/***** *****/
+/***** I N T E R F A C E *****/
+/***** *****/
+/*****************************************************************/
+/*****************************************************************/
+
+
+static int
+qemu_gps_init(GpsCallbacks* callbacks)
+{
+ GpsState* s = _gps_state;
+
+ if (!s->init)
+ gps_state_init(s, callbacks);
+
+ if (s->fd < 0)
+ return -1;
+
+ return 0;
+}
+
+static void
+qemu_gps_cleanup(void)
+{
+ GpsState* s = _gps_state;
+
+ if (s->init)
+ gps_state_done(s);
+}
+
+
+static int
+qemu_gps_start()
+{
+ GpsState* s = _gps_state;
+
+ if (!s->init) {
+ D("%s: called with uninitialized state !!", __FUNCTION__);
+ return -1;
+ }
+
+ D("%s: called", __FUNCTION__);
+ gps_state_start(s);
+ return 0;
+}
+
+
+static int
+qemu_gps_stop()
+{
+ GpsState* s = _gps_state;
+
+ if (!s->init) {
+ D("%s: called with uninitialized state !!", __FUNCTION__);
+ return -1;
+ }
+
+ D("%s: called", __FUNCTION__);
+ gps_state_stop(s);
+ return 0;
+}
+
+
+static int
+qemu_gps_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)
+{
+ return 0;
+}
+
+static int
+qemu_gps_inject_location(double latitude, double longitude, float accuracy)
+{
+ return 0;
+}
+
+static void
+qemu_gps_delete_aiding_data(GpsAidingData flags)
+{
+}
+
+static int qemu_gps_set_position_mode(GpsPositionMode mode, int fix_frequency)
+{
+ // FIXME - support fix_frequency
+ return 0;
+}
+
+static const void*
+qemu_gps_get_extension(const char* name)
+{
+ // no extensions supported
+ return NULL;
+}
+
+static const GpsInterface qemuGpsInterface = {
+ sizeof(GpsInterface),
+ qemu_gps_init,
+ qemu_gps_start,
+ qemu_gps_stop,
+ qemu_gps_cleanup,
+ qemu_gps_inject_time,
+ qemu_gps_inject_location,
+ qemu_gps_delete_aiding_data,
+ qemu_gps_set_position_mode,
+ qemu_gps_get_extension,
+};
+
+const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
+{
+ return &qemuGpsInterface;
+}
+
+static int open_gps(const struct hw_module_t* module, char const* name,
+ struct hw_device_t** device)
+{
+ struct gps_device_t *dev = malloc(sizeof(struct gps_device_t));
+ memset(dev, 0, sizeof(*dev));
+
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (struct hw_module_t*)module;
+// dev->common.close = (int (*)(struct hw_device_t*))close_lights;
+ dev->get_gps_interface = gps__get_gps_interface;
+
+ *device = (struct hw_device_t*)dev;
+ return 0;
+}
+
+
+static struct hw_module_methods_t gps_module_methods = {
+ .open = open_gps
+};
+
+const struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = GPS_HARDWARE_MODULE_ID,
+ .name = "Goldfish GPS Module",
+ .author = "The Android Open Source Project",
+ .methods = &gps_module_methods,
+};
diff --git a/tools/emulator/system/libqemu/test_guest_1.c b/tools/emulator/system/libqemu/test_guest_1.c
new file mode 100644
index 0000000..1a81000
--- /dev/null
+++ b/tools/emulator/system/libqemu/test_guest_1.c
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+/* This program uses a QEMUD pipe to exchange data with a test
+ * server. It's very simple:
+ *
+ * for count in range(0,100):
+ * msg = "Hello Word " + count
+ * qemud_pipe_send(msg)
+ * qemud_pipe_recv(msg2)
+ * if (msg != msg2):
+ * error()
+ *
+ *
+ * See test_host_1.c for the corresponding server code, which simply
+ * sends back anything it receives from the client.
+ */
+#include "test_util.h"
+#include <errno.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#define PIPE_NAME "pingpong"
+
+
+int main(void)
+{
+ Pipe pipe[1];
+ const int maxCount = 100;
+ int port = 8012;
+
+#if 0
+ if (pipe_openSocket(pipe, port) < 0) {
+ fprintf(stderr, "Could not open tcp socket!\n");
+ return 1;
+ }
+ printf("Connected to tcp:host:%d\n", port);
+#else
+ if (pipe_openQemuPipe(pipe, PIPE_NAME) < 0) {
+ fprintf(stderr, "Could not open '%s' pipe: %s\n", PIPE_NAME, strerror(errno));
+ return 1;
+ }
+ printf("Connected to '%s' pipe\n", PIPE_NAME);
+#endif
+
+ char buff[64];
+ char buff2[64];
+ int count;
+ double time0 = now_secs();
+ size_t total = 0;
+
+ for (count = 0; count < maxCount; count++) {
+ /* First, send a small message */
+ int len = snprintf(buff, sizeof(buff), "Hello World %d\n", count);
+ printf("%4d: Sending %d bytes\n", count, len);
+ int ret = pipe_send(pipe, buff, len);
+ if (ret < 0) {
+ fprintf(stderr,"Sending %d bytes failed: %s\n", len, strerror(errno));
+ return 1;
+ }
+
+ total += len;
+
+ /* The server is supposed to send the message back */
+ ret = pipe_recv(pipe, buff2, len);
+ if (ret < 0) {
+ fprintf(stderr, "Receiving failed (ret=%d): %s\n", ret, strerror(errno));
+ return 3;
+ }
+ printf("%4d: Received %d bytes\n", count, ret);
+ /* Check the message's content */
+ if (ret != len) {
+ fprintf(stderr, "Message size mismatch sent=%d received=%d\n", len, ret);
+ return 5;
+ }
+ if (memcmp(buff, buff2, len) != 0) {
+ fprintf(stderr, "Message content mismatch!\n");
+ return 6;
+ }
+ }
+
+ double time1 = now_secs();
+
+ printf("Closing pipe\n");
+ pipe_close(pipe);
+
+ printf("Bandwidth: %g MB/s, %g bytes in %g seconds.\n",
+ total*1.0 / (1024.*1024.*(time1-time0)), 1.0*total, time1-time0);
+
+ return 0;
+}
diff --git a/tools/emulator/system/libqemu/test_guest_2.c b/tools/emulator/system/libqemu/test_guest_2.c
new file mode 100644
index 0000000..c834098
--- /dev/null
+++ b/tools/emulator/system/libqemu/test_guest_2.c
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+
+/* This program benchmarks a QEMUD pipe to exchange data with a test
+ * server.
+ *
+ * See test_host_1.c for the corresponding server code, which simply
+ * sends back anything it receives from the client.
+ */
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include "test_util.h"
+
+#define PIPE_NAME "pingpong"
+
+char* progname;
+
+static void usage(int code)
+{
+ printf("Usage: %s [options]\n\n", progname);
+ printf(
+ "Valid options are:\n\n"
+ " -? -h --help Print this message\n"
+ " -pipe <name> Use pipe name (default: " PIPE_NAME ")\n"
+ " -tcp <port> Use local tcp port\n"
+ " -size <size> Specify packet size\n"
+ "\n"
+ );
+ exit(code);
+}
+
+int main(int argc, char** argv)
+{
+ Pipe pipe[1];
+ const char* tcpPort = NULL;
+ int localPort = 0;
+ const char* pipeName = NULL;
+ const char* packetSize = NULL;
+ int port = 8012;
+ int maxCount = 1000;
+ int bufferSize = 16384;
+ uint8_t* buffer;
+ uint8_t* buffer2;
+ int nn, count;
+ double time0, time1;
+
+ /* Extract program name */
+ {
+ char* p = strrchr(argv[0], '/');
+ if (p == NULL)
+ progname = argv[0];
+ else
+ progname = p+1;
+ }
+
+ /* Parse options */
+ while (argc > 1 && argv[1][0] == '-') {
+ char* arg = argv[1];
+ if (!strcmp(arg, "-?") || !strcmp(arg, "-h") || !strcmp(arg, "--help")) {
+ usage(0);
+ } else if (!strcmp(arg, "-pipe")) {
+ if (argc < 3) {
+ fprintf(stderr, "-pipe option needs an argument! See --help for details.\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ pipeName = argv[1];
+ } else if (!strcmp(arg, "-tcp")) {
+ if (argc < 3) {
+ fprintf(stderr, "-tcp option needs an argument! See --help for details.\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ tcpPort = argv[1];
+ } else if (!strcmp(arg, "-size")) {
+ if (argc < 3) {
+ fprintf(stderr, "-tcp option needs an argument! See --help for details.\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ packetSize = argv[1];
+ } else {
+ fprintf(stderr, "UNKNOWN OPTION: %s\n\n", arg);
+ usage(1);
+ }
+ argc--;
+ argv++;
+ }
+
+ /* Check arguments */
+ if (tcpPort && pipeName) {
+ fprintf(stderr, "You can't use both -pipe and -tcp at the same time\n");
+ exit(2);
+ }
+
+ if (tcpPort != NULL) {
+ localPort = atoi(tcpPort);
+ if (localPort <= 0 || localPort > 65535) {
+ fprintf(stderr, "Invalid port number: %s\n", tcpPort);
+ exit(2);
+ }
+ } else if (pipeName == NULL) {
+ /* Use default pipe name */
+ pipeName = PIPE_NAME;
+ }
+
+ if (packetSize != NULL) {
+ int size = atoi(packetSize);
+ if (size <= 0) {
+ fprintf(stderr, "Invalid byte size: %s\n", packetSize);
+ exit(3);
+ }
+ bufferSize = size;
+ }
+
+ /* Open the pipe */
+ if (tcpPort != NULL) {
+ if (pipe_openSocket(pipe, localPort) < 0) {
+ fprintf(stderr, "Could not open tcp socket!\n");
+ return 1;
+ }
+ printf("Connected to tcp:localhost:%d\n", port);
+ }
+ else {
+ if (pipe_openQemuPipe(pipe, pipeName) < 0) {
+ fprintf(stderr, "Could not open '%s' pipe: %s\n", pipeName, strerror(errno));
+ return 1;
+ }
+ printf("Connected to '%s' pipe\n", pipeName);
+ }
+
+ /* Allocate buffers, setup their data */
+ buffer = malloc(bufferSize);
+ buffer2 = malloc(bufferSize);
+
+ for (nn = 0; nn < bufferSize; nn++) {
+ buffer[nn] = (uint8_t)nn;
+ }
+
+ /* Do the work! */
+ time0 = now_secs();
+
+ for (count = 0; count < maxCount; count++) {
+ int ret = pipe_send(pipe, buffer, bufferSize);
+ int pos, len;
+
+ if (ret < 0) {
+ fprintf(stderr,"%d: Sending %d bytes failed: %s\n", count, bufferSize, strerror(errno));
+ return 1;
+ }
+
+#if 1
+ /* The server is supposed to send the message back */
+ pos = 0;
+ len = bufferSize;
+ while (len > 0) {
+ ret = pipe_recv(pipe, buffer2 + pos, len);
+ if (ret < 0) {
+ fprintf(stderr, "Receiving failed (ret=%d): %s\n", ret, strerror(errno));
+ return 3;
+ }
+ if (ret == 0) {
+ fprintf(stderr, "Disconnection while receiving!\n");
+ return 4;
+ }
+ pos += ret;
+ len -= ret;
+ }
+
+ if (memcmp(buffer, buffer2, bufferSize) != 0) {
+ fprintf(stderr, "Message content mismatch!\n");
+ const int maxAvail = 16;
+ const int maxLines = 12;
+ int numLines = 0;
+ for (nn = 0; nn < bufferSize; ) {
+ int avail = bufferSize - nn;
+ int mm;
+ if (avail > maxAvail)
+ avail = maxAvail;
+
+ if (memcmp(buffer+nn, buffer2+nn, avail) != 0) {
+ if (++numLines >= maxLines) {
+ printf(".... to be continued ...\n");
+ break;
+ }
+ printf("%04x:", nn);
+
+ for (mm = 0; mm < avail; mm++)
+ printf(" %02x", buffer[nn+mm]);
+ for ( ; mm < maxAvail; mm++ )
+ printf(" ");
+
+ printf( " -- " );
+
+ for (mm = 0; mm < avail; mm++)
+ printf(" %02x", buffer2[nn+mm]);
+
+ printf ("\n");
+ }
+ nn += avail;
+ }
+ return 6;
+ }
+
+#endif
+
+ if (count > 0 && (count % 200) == 0) {
+ printf("... %d\n", count);
+ }
+ }
+
+ time1 = now_secs();
+
+ printf("Closing pipe\n");
+ pipe_close(pipe);
+
+ printf("Total time: %g seconds\n", time1 - time0);
+ printf("Total bytes: %g bytes\n", 1.0*maxCount*bufferSize);
+ printf("Bandwidth: %g MB/s\n", (maxCount*bufferSize/(1024.0*1024.0))/(time1 - time0) );
+ return 0;
+}
diff --git a/tools/emulator/system/libqemu/test_host_1.c b/tools/emulator/system/libqemu/test_host_1.c
new file mode 100644
index 0000000..8e32bf2
--- /dev/null
+++ b/tools/emulator/system/libqemu/test_host_1.c
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+
+/* This program is used to test the QEMUD fast pipes.
+ * See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
+ *
+ * The program acts as a simple TCP server that accepts data and sends
+ * them back to the client as is.
+ */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* Default port number */
+#define DEFAULT_PORT 8012
+#define DEFAULT_PATH "/tmp/libqemu-socket"
+
+/* Try to execute x, looping around EINTR errors. */
+#undef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) ({ \
+ typeof (exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; })
+
+#define TFR TEMP_FAILURE_RETRY
+
+/* Close a socket, preserving the value of errno */
+static void
+socket_close(int sock)
+{
+ int old_errno = errno;
+ close(sock);
+ errno = old_errno;
+}
+
+/* Create a server socket bound to a loopback port */
+static int
+socket_loopback_server( int port, int type )
+{
+ struct sockaddr_in addr;
+
+ int sock = socket(AF_INET, type, 0);
+ if (sock < 0) {
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ int n = 1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+ if (TFR(bind(sock, (struct sockaddr*)&addr, sizeof(addr))) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+
+ if (type == SOCK_STREAM) {
+ if (TFR(listen(sock, 4)) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+ }
+
+ return sock;
+}
+
+static int
+socket_unix_server( const char* path, int type )
+{
+ struct sockaddr_un addr;
+
+ int sock = socket(AF_UNIX, type, 0);
+ if (sock < 0) {
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
+
+ unlink(addr.sun_path);
+
+ printf("Unix path: '%s'\n", addr.sun_path);
+
+ int n = 1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+ if (TFR(bind(sock, (struct sockaddr*)&addr, sizeof(addr))) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+
+ if (type == SOCK_STREAM) {
+ if (TFR(listen(sock, 4)) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+ }
+
+ return sock;
+}
+
+char* progname;
+
+static void usage(int code)
+{
+ printf("Usage: %s [options]\n\n", progname);
+ printf(
+ "Valid options are:\n\n"
+ " -? -h --help Print this message\n"
+ " -unix <path> Use unix server socket\n"
+ " -tcp <port> Use local tcp port (default %d)\n"
+ "\n", DEFAULT_PORT
+ );
+ exit(code);
+}
+
+/* Main program */
+int main(int argc, char** argv)
+{
+ int sock, client;
+ int port = DEFAULT_PORT;
+ const char* path = NULL;
+ const char* tcpPort = NULL;
+
+ /* Extract program name */
+ {
+ char* p = strrchr(argv[0], '/');
+ if (p == NULL)
+ progname = argv[0];
+ else
+ progname = p+1;
+ }
+
+ /* Parse options */
+ while (argc > 1 && argv[1][0] == '-') {
+ char* arg = argv[1];
+ if (!strcmp(arg, "-?") || !strcmp(arg, "-h") || !strcmp(arg, "--help")) {
+ usage(0);
+ } else if (!strcmp(arg, "-unix")) {
+ if (argc < 3) {
+ fprintf(stderr, "-unix option needs an argument! See --help for details.\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ path = argv[1];
+ } else if (!strcmp(arg, "-tcp")) {
+ if (argc < 3) {
+ fprintf(stderr, "-tcp option needs an argument! See --help for details.\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ tcpPort = argv[1];
+ } else {
+ fprintf(stderr, "UNKNOWN OPTION: %s\n\n", arg);
+ usage(1);
+ }
+ argc--;
+ argv++;
+ }
+
+ if (path != NULL) {
+ printf("Starting pipe test server on unix path: %s\n", path);
+ sock = socket_unix_server( path, SOCK_STREAM );
+ } else {
+ printf("Starting pipe test server on local port %d\n", port);
+ sock = socket_loopback_server( port, SOCK_STREAM );
+ }
+ if (sock < 0) {
+ fprintf(stderr, "Could not start server: %s\n", strerror(errno));
+ return 1;
+ }
+ printf("Server ready!\n");
+
+RESTART:
+ client = TFR(accept(sock, NULL, NULL));
+ if (client < 0) {
+ fprintf(stderr, "Server error: %s\n", strerror(errno));
+ return 2;
+ }
+ printf("Client connected!\n");
+
+ /* Now, accept any incoming data, and send it back */
+ for (;;) {
+ char buff[32768], *p;
+ int ret, count;
+
+ ret = TFR(read(client, buff, sizeof(buff)));
+ if (ret < 0) {
+ fprintf(stderr, "Client read error: %s\n", strerror(errno));
+ socket_close(client);
+ return 3;
+ }
+ if (ret == 0) {
+ break;
+ }
+ count = ret;
+ p = buff;
+ //printf(" received: %d bytes\n", count);
+
+ while (count > 0) {
+ ret = TFR(write(client, p, count));
+ if (ret < 0) {
+ fprintf(stderr, "Client write error: %s\n", strerror(errno));
+ socket_close(client);
+ return 4;
+ }
+ //printf(" sent: %d bytes\n", ret);
+
+ p += ret;
+ count -= ret;
+ }
+ }
+ printf("Client closed connection\n");
+ socket_close(client);
+ goto RESTART;
+
+ return 0;
+}
diff --git a/tools/emulator/system/libqemu/test_host_2.c b/tools/emulator/system/libqemu/test_host_2.c
new file mode 100644
index 0000000..46a9e8d
--- /dev/null
+++ b/tools/emulator/system/libqemu/test_host_2.c
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+/* This program is used to test the QEMUD fast pipes.
+ * See external/qemu/docs/ANDROID-QEMUD-PIPES.TXT for details.
+ *
+ * The program acts as a simple TCP server that accepts any data and
+ * discards it immediately.
+ */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* Default port number */
+#define DEFAULT_PORT 8012
+
+/* Try to execute x, looping around EINTR errors. */
+#undef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) ({ \
+ typeof (exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; })
+
+#define TFR TEMP_FAILURE_RETRY
+
+/* Close a socket, preserving the value of errno */
+static void
+socket_close(int sock)
+{
+ int old_errno = errno;
+ close(sock);
+ errno = old_errno;
+}
+
+/* Create a server socket bound to a loopback port */
+static int
+socket_loopback_server( int port, int type )
+{
+ struct sockaddr_in addr;
+
+ int sock = socket(AF_INET, type, 0);
+ if (sock < 0) {
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ int n = 1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
+
+ if (TFR(bind(sock, (struct sockaddr*)&addr, sizeof(addr))) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+
+ if (type == SOCK_STREAM) {
+ if (TFR(listen(sock, 4)) < 0) {
+ socket_close(sock);
+ return -1;
+ }
+ }
+
+ return sock;
+}
+
+/* Main program */
+int main(void)
+{
+ int sock, client;
+ int port = DEFAULT_PORT;
+
+ printf("Starting pipe test server on local port %d\n", port);
+ sock = socket_loopback_server( port, SOCK_STREAM );
+ if (sock < 0) {
+ fprintf(stderr, "Could not start server: %s\n", strerror(errno));
+ return 1;
+ }
+
+RESTART:
+ client = TFR(accept(sock, NULL, NULL));
+ if (client < 0) {
+ fprintf(stderr, "Server error: %s\n", strerror(errno));
+ return 2;
+ }
+ printf("Client connected!\n");
+
+ /* Now, accept any incoming data, and send it back */
+ for (;;) {
+ char buff[8192], *p;
+ int ret, count;
+
+ ret = TFR(read(client, buff, sizeof(buff)));
+ if (ret < 0) {
+ fprintf(stderr, "Client read error: %s\n", strerror(errno));
+ socket_close(client);
+ return 3;
+ }
+ if (ret == 0) {
+ break;
+ }
+ }
+ printf("Client closed connection\n");
+ socket_close(client);
+ goto RESTART;
+
+ return 0;
+}
diff --git a/tools/emulator/system/libqemu/test_util.c b/tools/emulator/system/libqemu/test_util.c
new file mode 100644
index 0000000..1696796
--- /dev/null
+++ b/tools/emulator/system/libqemu/test_util.c
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include "test_util.h"
+
+#ifdef __linux__
+#include <time.h>
+double now_secs(void)
+{
+ struct timespec tm;
+ clock_gettime(CLOCK_MONOTONIC, &tm);
+ return (double)tm.tv_sec + (double)tm.tv_nsec/1e9;
+}
+#else
+#include <sys/time.h>
+double now_secs(void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.sec + (double)tv.usec/1e6;
+}
+#endif
+
+int
+pipe_openSocket( Pipe* pipe, int port )
+{
+ static int fd;
+ struct sockaddr_in addr;
+
+ pipe->socket = -1;
+
+ fd = socket( AF_INET, SOCK_STREAM, 0 );
+ if (fd < 0) {
+ fprintf(stderr, "%s: Can't create socket!!\n", __FUNCTION__);
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(0x0a000202);
+
+ if ( connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0 ) {
+ fprintf(stderr, "%s: Can't connect to tcp:local:%d: %s\n",
+ __FUNCTION__, port, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ pipe->socket = fd;
+ return 0;
+}
+
+int
+pipe_openQemuPipe( Pipe* pipe, const char* pipename )
+{
+ pipe->socket = qemu_pipe_open(pipename);
+ if (pipe->socket < 0) {
+ fprintf(stderr, "%s: Could not open '%s' pipe: %s\n", __FUNCTION__, pipename, strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+int
+pipe_send( Pipe* pipe, const void* buff, size_t bufflen )
+{
+ int ret;
+ const uint8_t* ptr = buff;
+ while (bufflen > 0) {
+ ret = write(pipe->socket, ptr, bufflen);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno));
+ return -1;
+ }
+ if (ret == 0) {
+ fprintf(stderr, "%s: disconnection!\n", __FUNCTION__);
+ return -1;
+ }
+ ptr += ret;
+ bufflen -= ret;
+ }
+ return 0;
+}
+
+int
+pipe_recv( Pipe* pipe, void* buff, size_t bufflen )
+{
+ int ret;
+
+ for (;;) {
+ ret = read(pipe->socket, buff, bufflen);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno));
+ return -1;
+ }
+ if (ret == 0) {
+ fprintf(stderr, "%s: disconnection!\n", __FUNCTION__);
+ return -1;
+ }
+ break;
+ }
+ return ret;
+}
+
+void
+pipe_close( Pipe* pipe )
+{
+ if (pipe->socket >= 0) {
+ close(pipe->socket);
+ pipe->socket = -1;
+ }
+}
diff --git a/tools/emulator/system/libqemu/test_util.h b/tools/emulator/system/libqemu/test_util.h
new file mode 100644
index 0000000..28e5115c
--- /dev/null
+++ b/tools/emulator/system/libqemu/test_util.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+#ifndef TEST_UTIL_H
+#define TEST_UTIL_H
+
+#include <stddef.h>
+#include <hardware/qemu_pipe.h>
+
+
+double now_secs(void);
+
+typedef struct {
+ int socket;
+} Pipe;
+
+int pipe_openSocket( Pipe* pipe, int port );
+int pipe_openQemuPipe( Pipe* pipe, const char* pipename );
+int pipe_send( Pipe* pipe, const void* buff, size_t bufflen );
+int pipe_recv( Pipe* pipe, void* buff, size_t bufflen );
+void pipe_close( Pipe* pipe );
+
+#endif /* TEST_UTIL_H */
diff --git a/tools/emulator/system/libqemu/tests.mk b/tools/emulator/system/libqemu/tests.mk
new file mode 100644
index 0000000..3e89b23
--- /dev/null
+++ b/tools/emulator/system/libqemu/tests.mk
@@ -0,0 +1,30 @@
+# Build libqemu tests, included from main Android.mk
+
+# The first test program is a simple TCP server that will send back
+# anything it receives from the client.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-1
+LOCAL_SRC_FILES := test_host_1.c
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-2
+LOCAL_SRC_FILES := test_host_2.c
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-1
+LOCAL_SRC_FILES := test_guest_1.c test_util.c
+LOCAL_MODULE_TAGS := debug
+LOCAL_STATIC_LIBRARIES := libcutils
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := test-libqemu-2
+LOCAL_SRC_FILES := test_guest_2.c test_util.c
+LOCAL_MODULE_TAGS := debug
+LOCAL_STATIC_LIBRARIES := libcutils
+include $(BUILD_EXECUTABLE)
diff --git a/tools/emulator/system/lights/Android.mk b/tools/emulator/system/lights/Android.mk
new file mode 100644
index 0000000..c7aa83c
--- /dev/null
+++ b/tools/emulator/system/lights/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2011 The Android Open Source Project.
+#
+# Original code licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this software 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.
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(TARGET_PRODUCT),sim)
+# HAL module implemenation, not prelinked and stored in
+# hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_SRC_FILES := lights_qemu.c
+LOCAL_MODULE := lights.goldfish
+LOCAL_MODULE_TAGS := debug
+LOCAL_CFLAGS += -DLIGHT_BACKLIGHT
+include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/tools/emulator/system/lights/lights_qemu.c b/tools/emulator/system/lights/lights_qemu.c
new file mode 100644
index 0000000..d6576a0
--- /dev/null
+++ b/tools/emulator/system/lights/lights_qemu.c
@@ -0,0 +1,213 @@
+/* Copyright (C) 2011 The Android Open Source Project
+ *
+ * Original code licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this software 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 implements a lights hardware library for the Android emulator.
+ * the following code should be built as a shared library that will be
+ * placed into /system/lib/hw/lights.goldfish.so
+ *
+ * It will be loaded by the code in hardware/libhardware/hardware.c
+ * which is itself called from
+ * ./frameworks/base/services/jni/com_android_server_HardwareService.cpp
+ */
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#define LOG_TAG "Lights"
+#endif
+
+/* we connect with the emulator through the "hw-control" qemud service */
+#define LIGHTS_SERVICE_NAME "hw-control"
+
+#include <cutils/log.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <hardware/lights.h>
+#include <hardware/qemud.h>
+
+/* Set to 1 to enable debug messages to the log */
+#define DEBUG 0
+#if DEBUG
+# define D(...) LOGD(__VA_ARGS__)
+#else
+# define D(...) do{}while(0)
+#endif
+
+#define E(...) LOGE(__VA_ARGS__)
+
+/* Get brightness(0~255) from state. */
+static int
+rgb_to_brightness( struct light_state_t const* state )
+{
+ int color = state->color & 0x00ffffff;
+ return ((77 * ((color >> 16) & 0x00ff))
+ + (150 * ((color >> 8) & 0x00ff)) + (29 * (color & 0x00ff))) >> 8;
+}
+
+/* set backlight brightness by LIGHTS_SERVICE_NAME service. */
+static int
+set_light_backlight( struct light_device_t* dev, struct light_state_t const* state )
+{
+ /* Get Lights service. */
+ int fd = qemud_channel_open( LIGHTS_SERVICE_NAME );
+
+ if (fd < 0) {
+ E( "%s: no qemud connection", __FUNCTION__ );
+ return -1;
+ }
+
+ D( "%s: On/Off %d/%d flashMode %d brightnessMode %d"
+ " RGB = 0x%08x", __func__,
+ state->flashOnMS,
+ state->flashOffMS,
+ state->flashMode,
+ state->brightnessMode,
+ state->color );
+
+ int brightness = rgb_to_brightness( state );
+
+ char buffer[64];
+ snprintf( buffer, sizeof(buffer), "power:light:brightness:lcd_backlight:%d", brightness );
+ D( "%s: lcd_backlight command: %s", __FUNCTION__, buffer );
+
+ /* send backlight command to perform the backlight setting. */
+ if (qemud_channel_send( fd, buffer, -1 ) < 0) {
+ E( "%s: could not query lcd_backlight: %s", __FUNCTION__, strerror(errno) );
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ return 0;
+}
+
+static int
+set_light_buttons( struct light_device_t* dev, struct light_state_t const* state )
+{
+ /* @Waiting for later implementation. */
+ D( "%s: Not implemented.", __FUNCTION__ );
+
+ return 0;
+}
+
+static int
+set_light_battery( struct light_device_t* dev, struct light_state_t const* state )
+{
+ /* @Waiting for later implementation. */
+ D( "%s: Not implemented.", __FUNCTION__ );
+
+ return 0;
+}
+
+static int
+set_light_keyboard( struct light_device_t* dev, struct light_state_t const* state )
+{
+ /* @Waiting for later implementation. */
+ D( "%s: Not implemented.", __FUNCTION__ );
+
+ return 0;
+}
+
+static int
+set_light_notifications( struct light_device_t* dev, struct light_state_t const* state )
+{
+ /* @Waiting for later implementation. */
+ D( "%s: Not implemented.", __FUNCTION__ );
+
+ return 0;
+}
+
+static int
+set_light_attention( struct light_device_t* dev, struct light_state_t const* state )
+{
+ /* @Waiting for later implementation. */
+ D( "%s: Not implemented.", __FUNCTION__ );
+
+ return 0;
+}
+
+/** Close the lights device */
+static int
+close_lights( struct light_device_t *dev )
+{
+ free( dev );
+
+ return 0;
+}
+
+/**
+ * module methods
+ */
+
+/** Open a new instance of a lights device using name */
+static int
+open_lights( const struct hw_module_t* module, char const *name,
+ struct hw_device_t **device )
+{
+ void* set_light;
+
+ if (0 == strcmp( LIGHT_ID_BACKLIGHT, name )) {
+ set_light = set_light_backlight;
+ } else if (0 == strcmp( LIGHT_ID_KEYBOARD, name )) {
+ set_light = set_light_keyboard;
+ } else if (0 == strcmp( LIGHT_ID_BUTTONS, name )) {
+ set_light = set_light_buttons;
+ } else if (0 == strcmp( LIGHT_ID_BATTERY, name )) {
+ set_light = set_light_battery;
+ } else if (0 == strcmp( LIGHT_ID_NOTIFICATIONS, name )) {
+ set_light = set_light_notifications;
+ } else if (0 == strcmp( LIGHT_ID_ATTENTION, name )) {
+ set_light = set_light_attention;
+ } else {
+ D( "%s: %s light isn't supported yet.", __FUNCTION__, name );
+ return -EINVAL;
+ }
+
+ struct light_device_t *dev = malloc( sizeof(struct light_device_t) );
+ if (dev == NULL) {
+ return -EINVAL;
+ }
+ memset( dev, 0, sizeof(*dev) );
+
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = (struct hw_module_t*)module;
+ dev->common.close = (int (*)(struct hw_device_t*))close_lights;
+ dev->set_light = set_light;
+
+ *device = (struct hw_device_t*)dev;
+ return 0;
+}
+
+static struct hw_module_methods_t lights_module_methods = {
+ .open = open_lights,
+};
+
+/*
+ * The emulator lights Module
+ */
+const struct hw_module_t HAL_MODULE_INFO_SYM = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = LIGHTS_HARDWARE_MODULE_ID,
+ .name = "Goldfish lights Module",
+ .author = "The Android Open Source Project",
+ .methods = &lights_module_methods,
+};
diff --git a/tools/emulator/system/qemu-props/Android.mk b/tools/emulator/system/qemu-props/Android.mk
new file mode 100644
index 0000000..1bdbf68
--- /dev/null
+++ b/tools/emulator/system/qemu-props/Android.mk
@@ -0,0 +1,44 @@
+# Copyright (C) 2009 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 file is used to build emulator-specific program tools
+# that should only run in the emulator.
+#
+
+# We're moving the emulator-specific platform libs to
+# development.git/tools/emulator/. The following test is to ensure
+# smooth builds even if the tree contains both versions.
+#
+ifndef BUILD_EMULATOR_QEMU_PROPS
+BUILD_EMULATOR_QEMU_PROPS := true
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(TARGET_PRODUCT),sim)
+
+# The 'qemu-props' program is run from /system/etc/init.goldfish.rc
+# to setup various system properties sent by the emulator program.
+#
+include $(CLEAR_VARS)
+LOCAL_MODULE := qemu-props
+LOCAL_SRC_FILES := qemu-props.c
+LOCAL_SHARED_LIBRARIES := libcutils
+# we don't want this in 'user' builds which don't have
+# emulator-specific binaries.
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_EXECUTABLE)
+
+endif # TARGET_PRODUCT != sim
+
+endif # BUILD_EMULATOR_QEMU_PROPS
diff --git a/tools/emulator/system/qemu-props/qemu-props.c b/tools/emulator/system/qemu-props/qemu-props.c
new file mode 100644
index 0000000..3f086a1
--- /dev/null
+++ b/tools/emulator/system/qemu-props/qemu-props.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009 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 program is used to read a set of system properties and their values
+ * from the emulator program and set them in the currently-running emulated
+ * system. It does so by connecting to the 'boot-properties' qemud service.
+ *
+ * This program should be run as root and called from
+ * /system/etc/init.goldfish.rc exclusively.
+ */
+
+#define LOG_TAG "qemu-props"
+
+#define DEBUG 1
+
+#if DEBUG
+# include <cutils/log.h>
+# define DD(...) LOGI(__VA_ARGS__)
+#else
+# define DD(...) ((void)0)
+#endif
+
+#include <cutils/properties.h>
+#include <unistd.h>
+#include <hardware/qemud.h>
+
+/* Name of the qemud service we want to connect to.
+ */
+#define QEMUD_SERVICE "boot-properties"
+
+#define MAX_TRIES 5
+
+int main(void)
+{
+ int qemud_fd, count = 0;
+
+ /* try to connect to the qemud service */
+ {
+ int tries = MAX_TRIES;
+
+ while (1) {
+ qemud_fd = qemud_channel_open( "boot-properties" );
+ if (qemud_fd >= 0)
+ break;
+
+ if (--tries <= 0) {
+ DD("Could not connect after too many tries. Aborting");
+ return 1;
+ }
+
+ DD("waiting 1s to wait for qemud.");
+ sleep(1);
+ }
+ }
+
+ DD("connected to '%s' qemud service.", QEMUD_SERVICE);
+
+ /* send the 'list' command to the service */
+ if (qemud_channel_send(qemud_fd, "list", -1) < 0) {
+ DD("could not send command to '%s' service", QEMUD_SERVICE);
+ return 1;
+ }
+
+ /* read each system property as a single line from the service,
+ * until exhaustion.
+ */
+ for (;;)
+ {
+#define BUFF_SIZE (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
+ DD("receiving..");
+ char* q;
+ char temp[BUFF_SIZE];
+ int len = qemud_channel_recv(qemud_fd, temp, sizeof temp - 1);
+
+ /* lone NUL-byte signals end of properties */
+ if (len < 0 || len > BUFF_SIZE-1 || temp[0] == '\0')
+ break;
+
+ temp[len] = '\0'; /* zero-terminate string */
+
+ DD("received: %.*s", len, temp);
+
+ /* separate propery name from value */
+ q = strchr(temp, '=');
+ if (q == NULL) {
+ DD("invalid format, ignored.");
+ continue;
+ }
+ *q++ = '\0';
+
+ if (property_set(temp, q) < 0) {
+ DD("could not set property '%s' to '%s'", temp, q);
+ } else {
+ count += 1;
+ }
+ }
+
+
+ /* finally, close the channel and exit */
+ close(qemud_fd);
+ DD("exiting (%d properties set).", count);
+ return 0;
+}
diff --git a/tools/emulator/system/qemud/Android.mk b/tools/emulator/system/qemud/Android.mk
new file mode 100644
index 0000000..5666a74
--- /dev/null
+++ b/tools/emulator/system/qemud/Android.mk
@@ -0,0 +1,25 @@
+# Copyright 2008 The Android Open Source Project
+
+# We're moving the emulator-specific platform libs to
+# development.git/tools/emulator/. The following test is to ensure
+# smooth builds even if the tree contains both versions.
+#
+ifndef BUILD_EMULATOR_QEMUD
+BUILD_EMULATOR_QEMUD := true
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ qemud.c
+
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+
+LOCAL_MODULE:= qemud
+LOCAL_MODULE_TAGS := debug
+
+include $(BUILD_EXECUTABLE)
+
+endif # BUILD_EMULATOR_QEMUD
\ No newline at end of file
diff --git a/tools/emulator/system/qemud/qemud.c b/tools/emulator/system/qemud/qemud.c
new file mode 100644
index 0000000..dc04de8
--- /dev/null
+++ b/tools/emulator/system/qemud/qemud.c
@@ -0,0 +1,1719 @@
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <termios.h>
+#include <cutils/sockets.h>
+
+/*
+ * the qemud daemon program is only used within Android as a bridge
+ * between the emulator program and the emulated system. it really works as
+ * a simple stream multiplexer that works as follows:
+ *
+ * - qemud is started by init following instructions in
+ * /system/etc/init.goldfish.rc (i.e. it is never started on real devices)
+ *
+ * - qemud communicates with the emulator program through a single serial
+ * port, whose name is passed through a kernel boot parameter
+ * (e.g. android.qemud=ttyS1)
+ *
+ * - qemud binds one unix local stream socket (/dev/socket/qemud, created
+ * by init through /system/etc/init.goldfish.rc).
+ *
+ *
+ * emulator <==serial==> qemud <---> /dev/socket/qemud <-+--> client1
+ * |
+ * +--> client2
+ *
+ * - the special channel index 0 is used by the emulator and qemud only.
+ * other channel numbers correspond to clients. More specifically,
+ * connection are created like this:
+ *
+ * * the client connects to /dev/socket/qemud
+ *
+ * * the client sends the service name through the socket, as
+ * <service-name>
+ *
+ * * qemud creates a "Client" object internally, assigns it an
+ * internal unique channel number > 0, then sends a connection
+ * initiation request to the emulator (i.e. through channel 0):
+ *
+ * connect:<id>:<name>
+ *
+ * where <name> is the service name, and <id> is a 2-hexchar
+ * number corresponding to the channel number.
+ *
+ * * in case of success, the emulator responds through channel 0
+ * with:
+ *
+ * ok:connect:<id>
+ *
+ * after this, all messages between the client and the emulator
+ * are passed in pass-through mode.
+ *
+ * * if the emulator refuses the service connection, it will
+ * send the following through channel 0:
+ *
+ * ko:connect:<id>:reason-for-failure
+ *
+ * * If the client closes the connection, qemud sends the following
+ * to the emulator:
+ *
+ * disconnect:<id>
+ *
+ * The same message is the opposite direction if the emulator
+ * chooses to close the connection.
+ *
+ * * any command sent through channel 0 to the emulator that is
+ * not properly recognized will be answered by:
+ *
+ * ko:unknown command
+ *
+ *
+ * Internally, the daemon maintains a "Client" object for each client
+ * connection (i.e. accepting socket connection).
+ */
+
+/* name of the single control socket used by the daemon */
+#define CONTROL_SOCKET_NAME "qemud"
+
+#define DEBUG 0
+#define T_ACTIVE 0 /* set to 1 to dump traffic */
+
+#if DEBUG
+# define LOG_TAG "qemud"
+# include <cutils/log.h>
+# define D(...) LOGD(__VA_ARGS__)
+#else
+# define D(...) ((void)0)
+# define T(...) ((void)0)
+#endif
+
+#if T_ACTIVE
+# define T(...) D(__VA_ARGS__)
+#else
+# define T(...) ((void)0)
+#endif
+
+/** UTILITIES
+ **/
+
+static void
+fatal( const char* fmt, ... )
+{
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "PANIC: ");
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n" );
+ va_end(args);
+ exit(1);
+}
+
+static void*
+xalloc( size_t sz )
+{
+ void* p;
+
+ if (sz == 0)
+ return NULL;
+
+ p = malloc(sz);
+ if (p == NULL)
+ fatal( "not enough memory" );
+
+ return p;
+}
+
+#define xnew(p) (p) = xalloc(sizeof(*(p)))
+
+static void*
+xalloc0( size_t sz )
+{
+ void* p = xalloc(sz);
+ memset( p, 0, sz );
+ return p;
+}
+
+#define xnew0(p) (p) = xalloc0(sizeof(*(p)))
+
+#define xfree(p) (free((p)), (p) = NULL)
+
+static void*
+xrealloc( void* block, size_t size )
+{
+ void* p = realloc( block, size );
+
+ if (p == NULL && size > 0)
+ fatal( "not enough memory" );
+
+ return p;
+}
+
+#define xrenew(p,count) (p) = xrealloc((p),sizeof(*(p))*(count))
+
+static int
+hex2int( const uint8_t* data, int len )
+{
+ int result = 0;
+ while (len > 0) {
+ int c = *data++;
+ unsigned d;
+
+ result <<= 4;
+ do {
+ d = (unsigned)(c - '0');
+ if (d < 10)
+ break;
+
+ d = (unsigned)(c - 'a');
+ if (d < 6) {
+ d += 10;
+ break;
+ }
+
+ d = (unsigned)(c - 'A');
+ if (d < 6) {
+ d += 10;
+ break;
+ }
+
+ return -1;
+ }
+ while (0);
+
+ result |= d;
+ len -= 1;
+ }
+ return result;
+}
+
+
+static void
+int2hex( int value, uint8_t* to, int width )
+{
+ int nn = 0;
+ static const char hexchars[16] = "0123456789abcdef";
+
+ for ( --width; width >= 0; width--, nn++ ) {
+ to[nn] = hexchars[(value >> (width*4)) & 15];
+ }
+}
+
+static int
+fd_read(int fd, void* to, int len)
+{
+ int ret;
+
+ do {
+ ret = read(fd, to, len);
+ } while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
+static int
+fd_write(int fd, const void* from, int len)
+{
+ int ret;
+
+ do {
+ ret = write(fd, from, len);
+ } while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
+static void
+fd_setnonblock(int fd)
+{
+ int ret, flags;
+
+ do {
+ flags = fcntl(fd, F_GETFD);
+ } while (flags < 0 && errno == EINTR);
+
+ if (flags < 0) {
+ fatal( "%s: could not get flags for fd %d: %s",
+ __FUNCTION__, fd, strerror(errno) );
+ }
+
+ do {
+ ret = fcntl(fd, F_SETFD, flags | O_NONBLOCK);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret < 0) {
+ fatal( "%s: could not set fd %d to non-blocking: %s",
+ __FUNCTION__, fd, strerror(errno) );
+ }
+}
+
+
+static int
+fd_accept(int fd)
+{
+ struct sockaddr from;
+ socklen_t fromlen = sizeof(from);
+ int ret;
+
+ do {
+ ret = accept(fd, &from, &fromlen);
+ } while (ret < 0 && errno == EINTR);
+
+ return ret;
+}
+
+/** FD EVENT LOOP
+ **/
+
+/* A Looper object is used to monitor activity on one or more
+ * file descriptors (e.g sockets).
+ *
+ * - call looper_add() to register a function that will be
+ * called when events happen on the file descriptor.
+ *
+ * - call looper_enable() or looper_disable() to enable/disable
+ * the set of monitored events for a given file descriptor.
+ *
+ * - call looper_del() to unregister a file descriptor.
+ * this does *not* close the file descriptor.
+ *
+ * Note that you can only provide a single function to handle
+ * all events related to a given file descriptor.
+
+ * You can call looper_enable/_disable/_del within a function
+ * callback.
+ */
+
+/* the current implementation uses Linux's epoll facility
+ * the event mask we use are simply combinations of EPOLLIN
+ * EPOLLOUT, EPOLLHUP and EPOLLERR
+ */
+#include <sys/epoll.h>
+
+#define MAX_CHANNELS 16
+#define MAX_EVENTS (MAX_CHANNELS+1) /* each channel + the serial fd */
+
+/* the event handler function type, 'user' is a user-specific
+ * opaque pointer passed to looper_add().
+ */
+typedef void (*EventFunc)( void* user, int events );
+
+/* bit flags for the LoopHook structure.
+ *
+ * HOOK_PENDING means that an event happened on the
+ * corresponding file descriptor.
+ *
+ * HOOK_CLOSING is used to delay-close monitored
+ * file descriptors.
+ */
+enum {
+ HOOK_PENDING = (1 << 0),
+ HOOK_CLOSING = (1 << 1),
+};
+
+/* A LoopHook structure is used to monitor a given
+ * file descriptor and record its event handler.
+ */
+typedef struct {
+ int fd;
+ int wanted; /* events we are monitoring */
+ int events; /* events that occured */
+ int state; /* see HOOK_XXX constants */
+ void* ev_user; /* user-provided handler parameter */
+ EventFunc ev_func; /* event handler callback */
+} LoopHook;
+
+/* Looper is the main object modeling a looper object
+ */
+typedef struct {
+ int epoll_fd;
+ int num_fds;
+ int max_fds;
+ struct epoll_event* events;
+ LoopHook* hooks;
+} Looper;
+
+/* initialize a looper object */
+static void
+looper_init( Looper* l )
+{
+ l->epoll_fd = epoll_create(4);
+ l->num_fds = 0;
+ l->max_fds = 0;
+ l->events = NULL;
+ l->hooks = NULL;
+}
+
+/* finalize a looper object */
+static void
+looper_done( Looper* l )
+{
+ xfree(l->events);
+ xfree(l->hooks);
+ l->max_fds = 0;
+ l->num_fds = 0;
+
+ close(l->epoll_fd);
+ l->epoll_fd = -1;
+}
+
+/* return the LoopHook corresponding to a given
+ * monitored file descriptor, or NULL if not found
+ */
+static LoopHook*
+looper_find( Looper* l, int fd )
+{
+ LoopHook* hook = l->hooks;
+ LoopHook* end = hook + l->num_fds;
+
+ for ( ; hook < end; hook++ ) {
+ if (hook->fd == fd)
+ return hook;
+ }
+ return NULL;
+}
+
+/* grow the arrays in the looper object */
+static void
+looper_grow( Looper* l )
+{
+ int old_max = l->max_fds;
+ int new_max = old_max + (old_max >> 1) + 4;
+ int n;
+
+ xrenew( l->events, new_max );
+ xrenew( l->hooks, new_max );
+ l->max_fds = new_max;
+
+ /* now change the handles to all events */
+ for (n = 0; n < l->num_fds; n++) {
+ struct epoll_event ev;
+ LoopHook* hook = l->hooks + n;
+
+ ev.events = hook->wanted;
+ ev.data.ptr = hook;
+ epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
+ }
+}
+
+/* register a file descriptor and its event handler.
+ * no event mask will be enabled
+ */
+static void
+looper_add( Looper* l, int fd, EventFunc func, void* user )
+{
+ struct epoll_event ev;
+ LoopHook* hook;
+
+ if (l->num_fds >= l->max_fds)
+ looper_grow(l);
+
+ hook = l->hooks + l->num_fds;
+
+ hook->fd = fd;
+ hook->ev_user = user;
+ hook->ev_func = func;
+ hook->state = 0;
+ hook->wanted = 0;
+ hook->events = 0;
+
+ fd_setnonblock(fd);
+
+ ev.events = 0;
+ ev.data.ptr = hook;
+ epoll_ctl( l->epoll_fd, EPOLL_CTL_ADD, fd, &ev );
+
+ l->num_fds += 1;
+}
+
+/* unregister a file descriptor and its event handler
+ */
+static void
+looper_del( Looper* l, int fd )
+{
+ LoopHook* hook = looper_find( l, fd );
+
+ if (!hook) {
+ D( "%s: invalid fd: %d", __FUNCTION__, fd );
+ return;
+ }
+ /* don't remove the hook yet */
+ hook->state |= HOOK_CLOSING;
+
+ epoll_ctl( l->epoll_fd, EPOLL_CTL_DEL, fd, NULL );
+}
+
+/* enable monitoring of certain events for a file
+ * descriptor. This adds 'events' to the current
+ * event mask
+ */
+static void
+looper_enable( Looper* l, int fd, int events )
+{
+ LoopHook* hook = looper_find( l, fd );
+
+ if (!hook) {
+ D("%s: invalid fd: %d", __FUNCTION__, fd );
+ return;
+ }
+
+ if (events & ~hook->wanted) {
+ struct epoll_event ev;
+
+ hook->wanted |= events;
+ ev.events = hook->wanted;
+ ev.data.ptr = hook;
+
+ epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
+ }
+}
+
+/* disable monitoring of certain events for a file
+ * descriptor. This ignores events that are not
+ * currently enabled.
+ */
+static void
+looper_disable( Looper* l, int fd, int events )
+{
+ LoopHook* hook = looper_find( l, fd );
+
+ if (!hook) {
+ D("%s: invalid fd: %d", __FUNCTION__, fd );
+ return;
+ }
+
+ if (events & hook->wanted) {
+ struct epoll_event ev;
+
+ hook->wanted &= ~events;
+ ev.events = hook->wanted;
+ ev.data.ptr = hook;
+
+ epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, fd, &ev );
+ }
+}
+
+/* wait until an event occurs on one of the registered file
+ * descriptors. Only returns in case of error !!
+ */
+static void
+looper_loop( Looper* l )
+{
+ for (;;) {
+ int n, count;
+
+ do {
+ count = epoll_wait( l->epoll_fd, l->events, l->num_fds, -1 );
+ } while (count < 0 && errno == EINTR);
+
+ if (count < 0) {
+ D("%s: error: %s", __FUNCTION__, strerror(errno) );
+ return;
+ }
+
+ if (count == 0) {
+ D("%s: huh ? epoll returned count=0", __FUNCTION__);
+ continue;
+ }
+
+ /* mark all pending hooks */
+ for (n = 0; n < count; n++) {
+ LoopHook* hook = l->events[n].data.ptr;
+ hook->state = HOOK_PENDING;
+ hook->events = l->events[n].events;
+ }
+
+ /* execute hook callbacks. this may change the 'hooks'
+ * and 'events' array, as well as l->num_fds, so be careful */
+ for (n = 0; n < l->num_fds; n++) {
+ LoopHook* hook = l->hooks + n;
+ if (hook->state & HOOK_PENDING) {
+ hook->state &= ~HOOK_PENDING;
+ hook->ev_func( hook->ev_user, hook->events );
+ }
+ }
+
+ /* now remove all the hooks that were closed by
+ * the callbacks */
+ for (n = 0; n < l->num_fds;) {
+ struct epoll_event ev;
+ LoopHook* hook = l->hooks + n;
+
+ if (!(hook->state & HOOK_CLOSING)) {
+ n++;
+ continue;
+ }
+
+ hook[0] = l->hooks[l->num_fds-1];
+ l->num_fds -= 1;
+ ev.events = hook->wanted;
+ ev.data.ptr = hook;
+ epoll_ctl( l->epoll_fd, EPOLL_CTL_MOD, hook->fd, &ev );
+ }
+ }
+}
+
+#if T_ACTIVE
+char*
+quote( const void* data, int len )
+{
+ const char* p = data;
+ const char* end = p + len;
+ int count = 0;
+ int phase = 0;
+ static char* buff = NULL;
+
+ for (phase = 0; phase < 2; phase++) {
+ if (phase != 0) {
+ xfree(buff);
+ buff = xalloc(count+1);
+ }
+ count = 0;
+ for (p = data; p < end; p++) {
+ int c = *p;
+
+ if (c == '\\') {
+ if (phase != 0) {
+ buff[count] = buff[count+1] = '\\';
+ }
+ count += 2;
+ continue;
+ }
+
+ if (c >= 32 && c < 127) {
+ if (phase != 0)
+ buff[count] = c;
+ count += 1;
+ continue;
+ }
+
+
+ if (c == '\t') {
+ if (phase != 0) {
+ memcpy(buff+count, "<TAB>", 5);
+ }
+ count += 5;
+ continue;
+ }
+ if (c == '\n') {
+ if (phase != 0) {
+ memcpy(buff+count, "<LN>", 4);
+ }
+ count += 4;
+ continue;
+ }
+ if (c == '\r') {
+ if (phase != 0) {
+ memcpy(buff+count, "<CR>", 4);
+ }
+ count += 4;
+ continue;
+ }
+
+ if (phase != 0) {
+ buff[count+0] = '\\';
+ buff[count+1] = 'x';
+ buff[count+2] = "0123456789abcdef"[(c >> 4) & 15];
+ buff[count+3] = "0123456789abcdef"[ (c) & 15];
+ }
+ count += 4;
+ }
+ }
+ buff[count] = 0;
+ return buff;
+}
+#endif /* T_ACTIVE */
+
+/** PACKETS
+ **
+ ** We need a way to buffer data before it can be sent to the
+ ** corresponding file descriptor. We use linked list of Packet
+ ** objects to do this.
+ **/
+
+typedef struct Packet Packet;
+
+#define MAX_PAYLOAD 4000
+
+struct Packet {
+ Packet* next;
+ int len;
+ int channel;
+ uint8_t data[ MAX_PAYLOAD ];
+};
+
+/* we expect to alloc/free a lot of packets during
+ * operations so use a single linked list of free packets
+ * to keep things speedy and simple.
+ */
+static Packet* _free_packets;
+
+/* Allocate a packet */
+static Packet*
+packet_alloc(void)
+{
+ Packet* p = _free_packets;
+ if (p != NULL) {
+ _free_packets = p->next;
+ } else {
+ xnew(p);
+ }
+ p->next = NULL;
+ p->len = 0;
+ p->channel = -1;
+ return p;
+}
+
+/* Release a packet. This takes the address of a packet
+ * pointer that will be set to NULL on exit (avoids
+ * referencing dangling pointers in case of bugs)
+ */
+static void
+packet_free( Packet* *ppacket )
+{
+ Packet* p = *ppacket;
+ if (p) {
+ p->next = _free_packets;
+ _free_packets = p;
+ *ppacket = NULL;
+ }
+}
+
+/** PACKET RECEIVER
+ **
+ ** Simple abstraction for something that can receive a packet
+ ** from a FDHandler (see below) or something else.
+ **
+ ** Send a packet to it with 'receiver_post'
+ **
+ ** Call 'receiver_close' to indicate that the corresponding
+ ** packet source was closed.
+ **/
+
+typedef void (*PostFunc) ( void* user, Packet* p );
+typedef void (*CloseFunc)( void* user );
+
+typedef struct {
+ PostFunc post;
+ CloseFunc close;
+ void* user;
+} Receiver;
+
+/* post a packet to a receiver. Note that this transfers
+ * ownership of the packet to the receiver.
+ */
+static __inline__ void
+receiver_post( Receiver* r, Packet* p )
+{
+ if (r->post)
+ r->post( r->user, p );
+ else
+ packet_free(&p);
+}
+
+/* tell a receiver the packet source was closed.
+ * this will also prevent further posting to the
+ * receiver.
+ */
+static __inline__ void
+receiver_close( Receiver* r )
+{
+ if (r->close) {
+ r->close( r->user );
+ r->close = NULL;
+ }
+ r->post = NULL;
+}
+
+
+/** FD HANDLERS
+ **
+ ** these are smart listeners that send incoming packets to a receiver
+ ** and can queue one or more outgoing packets and send them when
+ ** possible to the FD.
+ **
+ ** note that we support clean shutdown of file descriptors,
+ ** i.e. we try to send all outgoing packets before destroying
+ ** the FDHandler.
+ **/
+
+typedef struct FDHandler FDHandler;
+typedef struct FDHandlerList FDHandlerList;
+
+struct FDHandler {
+ int fd;
+ FDHandlerList* list;
+ char closing;
+ Receiver receiver[1];
+
+ /* queue of outgoing packets */
+ int out_pos;
+ Packet* out_first;
+ Packet** out_ptail;
+
+ FDHandler* next;
+ FDHandler** pref;
+
+};
+
+struct FDHandlerList {
+ /* the looper that manages the fds */
+ Looper* looper;
+
+ /* list of active FDHandler objects */
+ FDHandler* active;
+
+ /* list of closing FDHandler objects.
+ * these are waiting to push their
+ * queued packets to the fd before
+ * freeing themselves.
+ */
+ FDHandler* closing;
+
+};
+
+/* remove a FDHandler from its current list */
+static void
+fdhandler_remove( FDHandler* f )
+{
+ f->pref[0] = f->next;
+ if (f->next)
+ f->next->pref = f->pref;
+}
+
+/* add a FDHandler to a given list */
+static void
+fdhandler_prepend( FDHandler* f, FDHandler** list )
+{
+ f->next = list[0];
+ f->pref = list;
+ list[0] = f;
+ if (f->next)
+ f->next->pref = &f->next;
+}
+
+/* initialize a FDHandler list */
+static void
+fdhandler_list_init( FDHandlerList* list, Looper* looper )
+{
+ list->looper = looper;
+ list->active = NULL;
+ list->closing = NULL;
+}
+
+
+/* close a FDHandler (and free it). Note that this will not
+ * perform a graceful shutdown, i.e. all packets in the
+ * outgoing queue will be immediately free.
+ *
+ * this *will* notify the receiver that the file descriptor
+ * was closed.
+ *
+ * you should call fdhandler_shutdown() if you want to
+ * notify the FDHandler that its packet source is closed.
+ */
+static void
+fdhandler_close( FDHandler* f )
+{
+ /* notify receiver */
+ receiver_close(f->receiver);
+
+ /* remove the handler from its list */
+ fdhandler_remove(f);
+
+ /* get rid of outgoing packet queue */
+ if (f->out_first != NULL) {
+ Packet* p;
+ while ((p = f->out_first) != NULL) {
+ f->out_first = p->next;
+ packet_free(&p);
+ }
+ }
+
+ /* get rid of file descriptor */
+ if (f->fd >= 0) {
+ looper_del( f->list->looper, f->fd );
+ close(f->fd);
+ f->fd = -1;
+ }
+
+ f->list = NULL;
+ xfree(f);
+}
+
+/* Ask the FDHandler to cleanly shutdown the connection,
+ * i.e. send any pending outgoing packets then auto-free
+ * itself.
+ */
+static void
+fdhandler_shutdown( FDHandler* f )
+{
+ /* prevent later fdhandler_close() to
+ * call the receiver's close.
+ */
+ f->receiver->close = NULL;
+
+ if (f->out_first != NULL && !f->closing)
+ {
+ /* move the handler to the 'closing' list */
+ f->closing = 1;
+ fdhandler_remove(f);
+ fdhandler_prepend(f, &f->list->closing);
+ return;
+ }
+
+ fdhandler_close(f);
+}
+
+/* Enqueue a new packet that the FDHandler will
+ * send through its file descriptor.
+ */
+static void
+fdhandler_enqueue( FDHandler* f, Packet* p )
+{
+ Packet* first = f->out_first;
+
+ p->next = NULL;
+ f->out_ptail[0] = p;
+ f->out_ptail = &p->next;
+
+ if (first == NULL) {
+ f->out_pos = 0;
+ looper_enable( f->list->looper, f->fd, EPOLLOUT );
+ }
+}
+
+
+/* FDHandler file descriptor event callback for read/write ops */
+static void
+fdhandler_event( FDHandler* f, int events )
+{
+ int len;
+
+ /* in certain cases, it's possible to have both EPOLLIN and
+ * EPOLLHUP at the same time. This indicates that there is incoming
+ * data to read, but that the connection was nonetheless closed
+ * by the sender. Be sure to read the data before closing
+ * the receiver to avoid packet loss.
+ */
+
+ if (events & EPOLLIN) {
+ Packet* p = packet_alloc();
+ int len;
+
+ if ((len = fd_read(f->fd, p->data, MAX_PAYLOAD)) < 0) {
+ D("%s: can't recv: %s", __FUNCTION__, strerror(errno));
+ packet_free(&p);
+ } else if (len > 0) {
+ p->len = len;
+ p->channel = -101; /* special debug value, not used */
+ receiver_post( f->receiver, p );
+ }
+ }
+
+ if (events & (EPOLLHUP|EPOLLERR)) {
+ /* disconnection */
+ D("%s: disconnect on fd %d", __FUNCTION__, f->fd);
+ fdhandler_close(f);
+ return;
+ }
+
+ if (events & EPOLLOUT && f->out_first) {
+ Packet* p = f->out_first;
+ int avail, len;
+
+ avail = p->len - f->out_pos;
+ if ((len = fd_write(f->fd, p->data + f->out_pos, avail)) < 0) {
+ D("%s: can't send: %s", __FUNCTION__, strerror(errno));
+ } else {
+ f->out_pos += len;
+ if (f->out_pos >= p->len) {
+ f->out_pos = 0;
+ f->out_first = p->next;
+ packet_free(&p);
+ if (f->out_first == NULL) {
+ f->out_ptail = &f->out_first;
+ looper_disable( f->list->looper, f->fd, EPOLLOUT );
+ }
+ }
+ }
+ }
+}
+
+
+/* Create a new FDHandler that monitors read/writes */
+static FDHandler*
+fdhandler_new( int fd,
+ FDHandlerList* list,
+ Receiver* receiver )
+{
+ FDHandler* f = xalloc0(sizeof(*f));
+
+ f->fd = fd;
+ f->list = list;
+ f->receiver[0] = receiver[0];
+ f->out_first = NULL;
+ f->out_ptail = &f->out_first;
+ f->out_pos = 0;
+
+ fdhandler_prepend(f, &list->active);
+
+ looper_add( list->looper, fd, (EventFunc) fdhandler_event, f );
+ looper_enable( list->looper, fd, EPOLLIN );
+
+ return f;
+}
+
+
+/* event callback function to monitor accepts() on server sockets.
+ * the convention used here is that the receiver will receive a
+ * dummy packet with the new client socket in p->channel
+ */
+static void
+fdhandler_accept_event( FDHandler* f, int events )
+{
+ if (events & EPOLLIN) {
+ /* this is an accept - send a dummy packet to the receiver */
+ Packet* p = packet_alloc();
+
+ D("%s: accepting on fd %d", __FUNCTION__, f->fd);
+ p->data[0] = 1;
+ p->len = 1;
+ p->channel = fd_accept(f->fd);
+ if (p->channel < 0) {
+ D("%s: accept failed ?: %s", __FUNCTION__, strerror(errno));
+ packet_free(&p);
+ return;
+ }
+ receiver_post( f->receiver, p );
+ }
+
+ if (events & (EPOLLHUP|EPOLLERR)) {
+ /* disconnecting !! */
+ D("%s: closing accept fd %d", __FUNCTION__, f->fd);
+ fdhandler_close(f);
+ return;
+ }
+}
+
+
+/* Create a new FDHandler used to monitor new connections on a
+ * server socket. The receiver must expect the new connection
+ * fd in the 'channel' field of a dummy packet.
+ */
+static FDHandler*
+fdhandler_new_accept( int fd,
+ FDHandlerList* list,
+ Receiver* receiver )
+{
+ FDHandler* f = xalloc0(sizeof(*f));
+
+ f->fd = fd;
+ f->list = list;
+ f->receiver[0] = receiver[0];
+
+ fdhandler_prepend(f, &list->active);
+
+ looper_add( list->looper, fd, (EventFunc) fdhandler_accept_event, f );
+ looper_enable( list->looper, fd, EPOLLIN );
+ listen( fd, 5 );
+
+ return f;
+}
+
+/** SERIAL CONNECTION STATE
+ **
+ ** The following is used to handle the framing protocol
+ ** used on the serial port connection.
+ **/
+
+/* each packet is made of a 6 byte header followed by a payload
+ * the header looks like:
+ *
+ * offset size description
+ * 0 2 a 2-byte hex string for the channel number
+ * 4 4 a 4-char hex string for the size of the payload
+ * 6 n the payload itself
+ */
+#define HEADER_SIZE 6
+#define CHANNEL_OFFSET 0
+#define LENGTH_OFFSET 2
+#define CHANNEL_SIZE 2
+#define LENGTH_SIZE 4
+
+#define CHANNEL_CONTROL 0
+
+/* The Serial object receives data from the serial port,
+ * extracts the payload size and channel index, then sends
+ * the resulting messages as a packet to a generic receiver.
+ *
+ * You can also use serial_send to send a packet through
+ * the serial port.
+ */
+typedef struct Serial {
+ FDHandler* fdhandler; /* used to monitor serial port fd */
+ Receiver receiver[1]; /* send payload there */
+ int in_len; /* current bytes in input packet */
+ int in_datalen; /* payload size, or 0 when reading header */
+ int in_channel; /* extracted channel number */
+ Packet* in_packet; /* used to read incoming packets */
+} Serial;
+
+
+/* a callback called when the serial port's fd is closed */
+static void
+serial_fd_close( Serial* s )
+{
+ fatal("unexpected serial port close !!");
+}
+
+static void
+serial_dump( Packet* p, const char* funcname )
+{
+ T("%s: %03d bytes: '%s'",
+ funcname, p->len, quote(p->data, p->len));
+}
+
+/* a callback called when a packet arrives from the serial port's FDHandler.
+ *
+ * This will essentially parse the header, extract the channel number and
+ * the payload size and store them in 'in_datalen' and 'in_channel'.
+ *
+ * After that, the payload is sent to the receiver once completed.
+ */
+static void
+serial_fd_receive( Serial* s, Packet* p )
+{
+ int rpos = 0, rcount = p->len;
+ Packet* inp = s->in_packet;
+ int inpos = s->in_len;
+
+ serial_dump( p, __FUNCTION__ );
+
+ while (rpos < rcount)
+ {
+ int avail = rcount - rpos;
+
+ /* first, try to read the header */
+ if (s->in_datalen == 0) {
+ int wanted = HEADER_SIZE - inpos;
+ if (avail > wanted)
+ avail = wanted;
+
+ memcpy( inp->data + inpos, p->data + rpos, avail );
+ inpos += avail;
+ rpos += avail;
+
+ if (inpos == HEADER_SIZE) {
+ s->in_datalen = hex2int( inp->data + LENGTH_OFFSET, LENGTH_SIZE );
+ s->in_channel = hex2int( inp->data + CHANNEL_OFFSET, CHANNEL_SIZE );
+
+ if (s->in_datalen <= 0) {
+ D("ignoring %s packet from serial port",
+ s->in_datalen ? "empty" : "malformed");
+ s->in_datalen = 0;
+ }
+
+ //D("received %d bytes packet for channel %d", s->in_datalen, s->in_channel);
+ inpos = 0;
+ }
+ }
+ else /* then, populate the packet itself */
+ {
+ int wanted = s->in_datalen - inpos;
+
+ if (avail > wanted)
+ avail = wanted;
+
+ memcpy( inp->data + inpos, p->data + rpos, avail );
+ inpos += avail;
+ rpos += avail;
+
+ if (inpos == s->in_datalen) {
+ if (s->in_channel < 0) {
+ D("ignoring %d bytes addressed to channel %d",
+ inpos, s->in_channel);
+ } else {
+ inp->len = inpos;
+ inp->channel = s->in_channel;
+ receiver_post( s->receiver, inp );
+ s->in_packet = inp = packet_alloc();
+ }
+ s->in_datalen = 0;
+ inpos = 0;
+ }
+ }
+ }
+ s->in_len = inpos;
+ packet_free(&p);
+}
+
+
+/* send a packet to the serial port.
+ * this assumes that p->len and p->channel contain the payload's
+ * size and channel and will add the appropriate header.
+ */
+static void
+serial_send( Serial* s, Packet* p )
+{
+ Packet* h = packet_alloc();
+
+ //D("sending to serial %d bytes from channel %d: '%.*s'", p->len, p->channel, p->len, p->data);
+
+ /* insert a small header before this packet */
+ h->len = HEADER_SIZE;
+ int2hex( p->len, h->data + LENGTH_OFFSET, LENGTH_SIZE );
+ int2hex( p->channel, h->data + CHANNEL_OFFSET, CHANNEL_SIZE );
+
+ serial_dump( h, __FUNCTION__ );
+ serial_dump( p, __FUNCTION__ );
+
+ fdhandler_enqueue( s->fdhandler, h );
+ fdhandler_enqueue( s->fdhandler, p );
+}
+
+
+/* initialize serial reader */
+static void
+serial_init( Serial* s,
+ int fd,
+ FDHandlerList* list,
+ Receiver* receiver )
+{
+ Receiver recv;
+
+ recv.user = s;
+ recv.post = (PostFunc) serial_fd_receive;
+ recv.close = (CloseFunc) serial_fd_close;
+
+ s->receiver[0] = receiver[0];
+
+ s->fdhandler = fdhandler_new( fd, list, &recv );
+ s->in_len = 0;
+ s->in_datalen = 0;
+ s->in_channel = 0;
+ s->in_packet = packet_alloc();
+}
+
+
+/** CLIENTS
+ **/
+
+typedef struct Client Client;
+typedef struct Multiplexer Multiplexer;
+
+/* A Client object models a single qemud client socket
+ * connection in the emulated system.
+ *
+ * the client first sends the name of the system service
+ * it wants to contact (no framing), then waits for a 2
+ * byte answer from qemud.
+ *
+ * the answer is either "OK" or "KO" to indicate
+ * success or failure.
+ *
+ * In case of success, the client can send messages
+ * to the service.
+ *
+ * In case of failure, it can disconnect or try sending
+ * the name of another service.
+ */
+struct Client {
+ Client* next;
+ Client** pref;
+ int channel;
+ char registered;
+ FDHandler* fdhandler;
+ Multiplexer* multiplexer;
+};
+
+struct Multiplexer {
+ Client* clients;
+ int last_channel;
+ Serial serial[1];
+ Looper looper[1];
+ FDHandlerList fdhandlers[1];
+};
+
+
+static int multiplexer_open_channel( Multiplexer* mult, Packet* p );
+static void multiplexer_close_channel( Multiplexer* mult, int channel );
+static void multiplexer_serial_send( Multiplexer* mult, int channel, Packet* p );
+
+static void
+client_dump( Client* c, Packet* p, const char* funcname )
+{
+ T("%s: client %p (%d): %3d bytes: '%s'",
+ funcname, c, c->fdhandler->fd,
+ p->len, quote(p->data, p->len));
+}
+
+/* destroy a client */
+static void
+client_free( Client* c )
+{
+ /* remove from list */
+ c->pref[0] = c->next;
+ if (c->next)
+ c->next->pref = c->pref;
+
+ c->channel = -1;
+ c->registered = 0;
+
+ /* gently ask the FDHandler to shutdown to
+ * avoid losing queued outgoing packets */
+ if (c->fdhandler != NULL) {
+ fdhandler_shutdown(c->fdhandler);
+ c->fdhandler = NULL;
+ }
+
+ xfree(c);
+}
+
+
+/* a function called when a client socket receives data */
+static void
+client_fd_receive( Client* c, Packet* p )
+{
+ client_dump(c, p, __FUNCTION__);
+
+ if (c->registered) {
+ /* the client is registered, just send the
+ * data through the serial port
+ */
+ multiplexer_serial_send(c->multiplexer, c->channel, p);
+ return;
+ }
+
+ if (c->channel > 0) {
+ /* the client is waiting registration results.
+ * this should not happen because the client
+ * should wait for our 'ok' or 'ko'.
+ * close the connection.
+ */
+ D("%s: bad client sending data before end of registration",
+ __FUNCTION__);
+ BAD_CLIENT:
+ packet_free(&p);
+ client_free(c);
+ return;
+ }
+
+ /* the client hasn't registered a service yet,
+ * so this must be the name of a service, call
+ * the multiplexer to start registration for
+ * it.
+ */
+ D("%s: attempting registration for service '%.*s'",
+ __FUNCTION__, p->len, p->data);
+ c->channel = multiplexer_open_channel(c->multiplexer, p);
+ if (c->channel < 0) {
+ D("%s: service name too long", __FUNCTION__);
+ goto BAD_CLIENT;
+ }
+ D("%s: -> received channel id %d", __FUNCTION__, c->channel);
+ packet_free(&p);
+}
+
+
+/* a function called when the client socket is closed. */
+static void
+client_fd_close( Client* c )
+{
+ T("%s: client %p (%d)", __FUNCTION__, c, c->fdhandler->fd);
+
+ /* no need to shutdown the FDHandler */
+ c->fdhandler = NULL;
+
+ /* tell the emulator we're out */
+ if (c->channel > 0)
+ multiplexer_close_channel(c->multiplexer, c->channel);
+
+ /* free the client */
+ client_free(c);
+}
+
+/* a function called when the multiplexer received a registration
+ * response from the emulator for a given client.
+ */
+static void
+client_registration( Client* c, int registered )
+{
+ Packet* p = packet_alloc();
+
+ /* sends registration status to client */
+ if (!registered) {
+ D("%s: registration failed for client %d", __FUNCTION__, c->channel);
+ memcpy( p->data, "KO", 2 );
+ p->len = 2;
+ } else {
+ D("%s: registration succeeded for client %d", __FUNCTION__, c->channel);
+ memcpy( p->data, "OK", 2 );
+ p->len = 2;
+ }
+ client_dump(c, p, __FUNCTION__);
+ fdhandler_enqueue(c->fdhandler, p);
+
+ /* now save registration state
+ */
+ c->registered = registered;
+ if (!registered) {
+ /* allow the client to try registering another service */
+ c->channel = -1;
+ }
+}
+
+/* send data to a client */
+static void
+client_send( Client* c, Packet* p )
+{
+ client_dump(c, p, __FUNCTION__);
+ fdhandler_enqueue(c->fdhandler, p);
+}
+
+
+/* Create new client socket handler */
+static Client*
+client_new( Multiplexer* mult,
+ int fd,
+ FDHandlerList* pfdhandlers,
+ Client** pclients )
+{
+ Client* c;
+ Receiver recv;
+
+ xnew(c);
+
+ c->multiplexer = mult;
+ c->next = NULL;
+ c->pref = &c->next;
+ c->channel = -1;
+ c->registered = 0;
+
+ recv.user = c;
+ recv.post = (PostFunc) client_fd_receive;
+ recv.close = (CloseFunc) client_fd_close;
+
+ c->fdhandler = fdhandler_new( fd, pfdhandlers, &recv );
+
+ /* add to client list */
+ c->next = *pclients;
+ c->pref = pclients;
+ *pclients = c;
+ if (c->next)
+ c->next->pref = &c->next;
+
+ return c;
+}
+
+/** GLOBAL MULTIPLEXER
+ **/
+
+/* find a client by its channel */
+static Client*
+multiplexer_find_client( Multiplexer* mult, int channel )
+{
+ Client* c = mult->clients;
+
+ for ( ; c != NULL; c = c->next ) {
+ if (c->channel == channel)
+ return c;
+ }
+ return NULL;
+}
+
+/* handle control messages coming from the serial port
+ * on CONTROL_CHANNEL.
+ */
+static void
+multiplexer_handle_control( Multiplexer* mult, Packet* p )
+{
+ /* connection registration success */
+ if (p->len == 13 && !memcmp(p->data, "ok:connect:", 11)) {
+ int channel = hex2int(p->data+11, 2);
+ Client* client = multiplexer_find_client(mult, channel);
+
+ /* note that 'client' can be NULL if the corresponding
+ * socket was closed before the emulator response arrived.
+ */
+ if (client != NULL) {
+ client_registration(client, 1);
+ } else {
+ D("%s: NULL client: '%.*s'", __FUNCTION__, p->len, p->data+11);
+ }
+ goto EXIT;
+ }
+
+ /* connection registration failure */
+ if (p->len == 13 && !memcmp(p->data, "ko:connect:",11)) {
+ int channel = hex2int(p->data+11, 2);
+ Client* client = multiplexer_find_client(mult, channel);
+
+ if (client != NULL)
+ client_registration(client, 0);
+
+ goto EXIT;
+ }
+
+ /* emulator-induced client disconnection */
+ if (p->len == 13 && !memcmp(p->data, "disconnect:",11)) {
+ int channel = hex2int(p->data+11, 2);
+ Client* client = multiplexer_find_client(mult, channel);
+
+ if (client != NULL)
+ client_free(client);
+
+ goto EXIT;
+ }
+
+ /* A message that begins with "X00" is a probe sent by
+ * the emulator used to detect which version of qemud it runs
+ * against (in order to detect 1.0/1.1 system images. Just
+ * silently ignore it there instead of printing an error
+ * message.
+ */
+ if (p->len >= 3 && !memcmp(p->data,"X00",3)) {
+ goto EXIT;
+ }
+
+ D("%s: unknown control message (%d bytes): '%.*s'",
+ __FUNCTION__, p->len, p->len, p->data);
+
+EXIT:
+ packet_free(&p);
+}
+
+/* a function called when an incoming packet comes from the serial port */
+static void
+multiplexer_serial_receive( Multiplexer* mult, Packet* p )
+{
+ Client* client;
+
+ T("%s: channel=%d '%.*s'", __FUNCTION__, p->channel, p->len, p->data);
+
+ if (p->channel == CHANNEL_CONTROL) {
+ multiplexer_handle_control(mult, p);
+ return;
+ }
+
+ client = multiplexer_find_client(mult, p->channel);
+ if (client != NULL) {
+ client_send(client, p);
+ return;
+ }
+
+ D("%s: discarding packet for unknown channel %d", __FUNCTION__, p->channel);
+ packet_free(&p);
+}
+
+/* a function called when the serial reader closes */
+static void
+multiplexer_serial_close( Multiplexer* mult )
+{
+ fatal("unexpected close of serial reader");
+}
+
+/* a function called to send a packet to the serial port */
+static void
+multiplexer_serial_send( Multiplexer* mult, int channel, Packet* p )
+{
+ p->channel = channel;
+ serial_send( mult->serial, p );
+}
+
+
+
+/* a function used by a client to allocate a new channel id and
+ * ask the emulator to open it. 'service' must be a packet containing
+ * the name of the service in its payload.
+ *
+ * returns -1 if the service name is too long.
+ *
+ * notice that client_registration() will be called later when
+ * the answer arrives.
+ */
+static int
+multiplexer_open_channel( Multiplexer* mult, Packet* service )
+{
+ Packet* p = packet_alloc();
+ int len, channel;
+
+ /* find a free channel number, assume we don't have many
+ * clients here. */
+ {
+ Client* c;
+ TRY_AGAIN:
+ channel = (++mult->last_channel) & 0xff;
+
+ for (c = mult->clients; c != NULL; c = c->next)
+ if (c->channel == channel)
+ goto TRY_AGAIN;
+ }
+
+ len = snprintf((char*)p->data, sizeof p->data, "connect:%.*s:%02x", service->len, service->data, channel);
+ if (len >= (int)sizeof(p->data)) {
+ D("%s: weird, service name too long (%d > %d)", __FUNCTION__, len, sizeof(p->data));
+ packet_free(&p);
+ return -1;
+ }
+ p->channel = CHANNEL_CONTROL;
+ p->len = len;
+
+ serial_send(mult->serial, p);
+ return channel;
+}
+
+/* used to tell the emulator a channel was closed by a client */
+static void
+multiplexer_close_channel( Multiplexer* mult, int channel )
+{
+ Packet* p = packet_alloc();
+ int len = snprintf((char*)p->data, sizeof(p->data), "disconnect:%02x", channel);
+
+ if (len > (int)sizeof(p->data)) {
+ /* should not happen */
+ return;
+ }
+
+ p->channel = CHANNEL_CONTROL;
+ p->len = len;
+
+ serial_send(mult->serial, p);
+}
+
+/* this function is used when a new connection happens on the control
+ * socket.
+ */
+static void
+multiplexer_control_accept( Multiplexer* m, Packet* p )
+{
+ /* the file descriptor for the new socket connection is
+ * in p->channel. See fdhandler_accept_event() */
+ int fd = p->channel;
+ Client* client = client_new( m, fd, m->fdhandlers, &m->clients );
+
+ D("created client %p listening on fd %d", client, fd);
+
+ /* free dummy packet */
+ packet_free(&p);
+}
+
+static void
+multiplexer_control_close( Multiplexer* m )
+{
+ fatal("unexpected multiplexer control close");
+}
+
+static void
+multiplexer_init( Multiplexer* m, const char* serial_dev )
+{
+ int fd, control_fd;
+ Receiver recv;
+
+ /* initialize looper and fdhandlers list */
+ looper_init( m->looper );
+ fdhandler_list_init( m->fdhandlers, m->looper );
+
+ /* open the serial port */
+ do {
+ fd = open(serial_dev, O_RDWR);
+ } while (fd < 0 && errno == EINTR);
+
+ if (fd < 0) {
+ fatal( "%s: could not open '%s': %s", __FUNCTION__, serial_dev,
+ strerror(errno) );
+ }
+ // disable echo on serial lines
+ if ( !memcmp( serial_dev, "/dev/ttyS", 9 ) ) {
+ struct termios ios;
+ tcgetattr( fd, &ios );
+ ios.c_lflag = 0; /* disable ECHO, ICANON, etc... */
+ tcsetattr( fd, TCSANOW, &ios );
+ }
+
+ /* initialize the serial reader/writer */
+ recv.user = m;
+ recv.post = (PostFunc) multiplexer_serial_receive;
+ recv.close = (CloseFunc) multiplexer_serial_close;
+
+ serial_init( m->serial, fd, m->fdhandlers, &recv );
+
+ /* open the qemud control socket */
+ recv.user = m;
+ recv.post = (PostFunc) multiplexer_control_accept;
+ recv.close = (CloseFunc) multiplexer_control_close;
+
+ fd = android_get_control_socket(CONTROL_SOCKET_NAME);
+ if (fd < 0) {
+ fatal("couldn't get fd for control socket '%s'", CONTROL_SOCKET_NAME);
+ }
+
+ fdhandler_new_accept( fd, m->fdhandlers, &recv );
+
+ /* initialize clients list */
+ m->clients = NULL;
+}
+
+/** MAIN LOOP
+ **/
+
+static Multiplexer _multiplexer[1];
+
+int main( void )
+{
+ Multiplexer* m = _multiplexer;
+
+ /* extract the name of our serial device from the kernel
+ * boot options that are stored in /proc/cmdline
+ */
+#define KERNEL_OPTION "android.qemud="
+
+ {
+ char buff[1024];
+ int fd, len;
+ char* p;
+ char* q;
+
+ fd = open( "/proc/cmdline", O_RDONLY );
+ if (fd < 0) {
+ D("%s: can't open /proc/cmdline !!: %s", __FUNCTION__,
+ strerror(errno));
+ exit(1);
+ }
+
+ len = fd_read( fd, buff, sizeof(buff)-1 );
+ close(fd);
+ if (len < 0) {
+ D("%s: can't read /proc/cmdline: %s", __FUNCTION__,
+ strerror(errno));
+ exit(1);
+ }
+ buff[len] = 0;
+
+ p = strstr( buff, KERNEL_OPTION );
+ if (p == NULL) {
+ D("%s: can't find '%s' in /proc/cmdline",
+ __FUNCTION__, KERNEL_OPTION );
+ exit(1);
+ }
+
+ p += sizeof(KERNEL_OPTION)-1; /* skip option */
+ q = p;
+ while ( *q && *q != ' ' && *q != '\t' )
+ q += 1;
+
+ snprintf( buff, sizeof(buff), "/dev/%.*s", q-p, p );
+
+ multiplexer_init( m, buff );
+ }
+
+ D( "entering main loop");
+ looper_loop( m->looper );
+ D( "unexpected termination !!" );
+ return 0;
+}
diff --git a/tools/emulator/system/sensors/Android.mk b/tools/emulator/system/sensors/Android.mk
new file mode 100644
index 0000000..9b0e83d
--- /dev/null
+++ b/tools/emulator/system/sensors/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2009 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.
+
+
+# We're moving the emulator-specific platform libs to
+# development.git/tools/emulator/. The following test is to ensure
+# smooth builds even if the tree contains both versions.
+#
+ifndef BUILD_EMULATOR_SENSORS_MODULE
+BUILD_EMULATOR_SENSORS_MODULE := true
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(TARGET_PRODUCT),sim)
+# HAL module implemenation, not prelinked and stored in
+# hw/<SENSORS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+include $(CLEAR_VARS)
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_SRC_FILES := sensors_qemu.c
+LOCAL_MODULE := sensors.goldfish
+LOCAL_MODULE_TAGS := debug
+include $(BUILD_SHARED_LIBRARY)
+endif
+
+endif # BUILD_EMULATOR_SENSORS_MODULE
diff --git a/tools/emulator/system/sensors/sensors_qemu.c b/tools/emulator/system/sensors/sensors_qemu.c
new file mode 100644
index 0000000..9a776c7
--- /dev/null
+++ b/tools/emulator/system/sensors/sensors_qemu.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright (C) 2009 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 implements a sensors hardware library for the Android emulator.
+ * the following code should be built as a shared library that will be
+ * placed into /system/lib/hw/sensors.goldfish.so
+ *
+ * it will be loaded by the code in hardware/libhardware/hardware.c
+ * which is itself called from com_android_server_SensorService.cpp
+ */
+
+
+/* we connect with the emulator through the "sensors" qemud service
+ */
+#define SENSORS_SERVICE_NAME "sensors"
+
+#define LOG_TAG "QemuSensors"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+#include <cutils/sockets.h>
+#include <hardware/sensors.h>
+
+#if 0
+#define D(...) LOGD(__VA_ARGS__)
+#else
+#define D(...) ((void)0)
+#endif
+
+#define E(...) LOGE(__VA_ARGS__)
+
+#include <hardware/qemud.h>
+
+/** SENSOR IDS AND NAMES
+ **/
+
+#define MAX_NUM_SENSORS 5
+
+#define SUPPORTED_SENSORS ((1<<MAX_NUM_SENSORS)-1)
+
+#define ID_BASE SENSORS_HANDLE_BASE
+#define ID_ACCELERATION (ID_BASE+0)
+#define ID_MAGNETIC_FIELD (ID_BASE+1)
+#define ID_ORIENTATION (ID_BASE+2)
+#define ID_TEMPERATURE (ID_BASE+3)
+#define ID_PROXIMITY (ID_BASE+4)
+
+#define SENSORS_ACCELERATION (1 << ID_ACCELERATION)
+#define SENSORS_MAGNETIC_FIELD (1 << ID_MAGNETIC_FIELD)
+#define SENSORS_ORIENTATION (1 << ID_ORIENTATION)
+#define SENSORS_TEMPERATURE (1 << ID_TEMPERATURE)
+#define SENSORS_PROXIMITY (1 << ID_PROXIMITY)
+
+#define ID_CHECK(x) ((unsigned)((x)-ID_BASE) < MAX_NUM_SENSORS)
+
+#define SENSORS_LIST \
+ SENSOR_(ACCELERATION,"acceleration") \
+ SENSOR_(MAGNETIC_FIELD,"magnetic-field") \
+ SENSOR_(ORIENTATION,"orientation") \
+ SENSOR_(TEMPERATURE,"temperature") \
+ SENSOR_(PROXIMITY,"proximity") \
+
+static const struct {
+ const char* name;
+ int id; } _sensorIds[MAX_NUM_SENSORS] =
+{
+#define SENSOR_(x,y) { y, ID_##x },
+ SENSORS_LIST
+#undef SENSOR_
+};
+
+static const char*
+_sensorIdToName( int id )
+{
+ int nn;
+ for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
+ if (id == _sensorIds[nn].id)
+ return _sensorIds[nn].name;
+ return "<UNKNOWN>";
+}
+
+static int
+_sensorIdFromName( const char* name )
+{
+ int nn;
+
+ if (name == NULL)
+ return -1;
+
+ for (nn = 0; nn < MAX_NUM_SENSORS; nn++)
+ if (!strcmp(name, _sensorIds[nn].name))
+ return _sensorIds[nn].id;
+
+ return -1;
+}
+
+/** SENSORS POLL DEVICE
+ **
+ ** This one is used to read sensor data from the hardware.
+ ** We implement this by simply reading the data from the
+ ** emulator through the QEMUD channel.
+ **/
+
+typedef struct SensorPoll {
+ struct sensors_poll_device_t device;
+ sensors_event_t sensors[MAX_NUM_SENSORS];
+ int events_fd;
+ uint32_t pendingSensors;
+ int64_t timeStart;
+ int64_t timeOffset;
+ int fd;
+ uint32_t active_sensors;
+} SensorPoll;
+
+/* this must return a file descriptor that will be used to read
+ * the sensors data (it is passed to data__data_open() below
+ */
+static native_handle_t*
+control__open_data_source(struct sensors_poll_device_t *dev)
+{
+ SensorPoll* ctl = (void*)dev;
+ native_handle_t* handle;
+
+ if (ctl->fd < 0) {
+ ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
+ }
+ D("%s: fd=%d", __FUNCTION__, ctl->fd);
+ handle = native_handle_create(1, 0);
+ handle->data[0] = dup(ctl->fd);
+ return handle;
+}
+
+static int
+control__activate(struct sensors_poll_device_t *dev,
+ int handle,
+ int enabled)
+{
+ SensorPoll* ctl = (void*)dev;
+ uint32_t mask, sensors, active, new_sensors, changed;
+ char command[128];
+ int ret;
+
+ D("%s: handle=%s (%d) fd=%d enabled=%d", __FUNCTION__,
+ _sensorIdToName(handle), handle, ctl->fd, enabled);
+
+ if (!ID_CHECK(handle)) {
+ E("%s: bad handle ID", __FUNCTION__);
+ return -1;
+ }
+
+ mask = (1<<handle);
+ sensors = enabled ? mask : 0;
+
+ active = ctl->active_sensors;
+ new_sensors = (active & ~mask) | (sensors & mask);
+ changed = active ^ new_sensors;
+
+ if (!changed)
+ return 0;
+
+ snprintf(command, sizeof command, "set:%s:%d",
+ _sensorIdToName(handle), enabled != 0);
+
+ if (ctl->fd < 0) {
+ ctl->fd = qemud_channel_open(SENSORS_SERVICE_NAME);
+ }
+
+ ret = qemud_channel_send(ctl->fd, command, -1);
+ if (ret < 0) {
+ E("%s: when sending command errno=%d: %s", __FUNCTION__, errno, strerror(errno));
+ return -1;
+ }
+ ctl->active_sensors = new_sensors;
+
+ return 0;
+}
+
+static int
+control__set_delay(struct sensors_poll_device_t *dev, int32_t ms)
+{
+ SensorPoll* ctl = (void*)dev;
+ char command[128];
+
+ D("%s: dev=%p delay-ms=%d", __FUNCTION__, dev, ms);
+
+ snprintf(command, sizeof command, "set-delay:%d", ms);
+
+ return qemud_channel_send(ctl->fd, command, -1);
+}
+
+static int
+control__close(struct hw_device_t *dev)
+{
+ SensorPoll* ctl = (void*)dev;
+ close(ctl->fd);
+ free(ctl);
+ return 0;
+}
+
+/* return the current time in nanoseconds */
+static int64_t
+data__now_ns(void)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ return (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
+}
+
+static int
+data__data_open(struct sensors_poll_device_t *dev, native_handle_t* handle)
+{
+ SensorPoll* data = (void*)dev;
+ int i;
+ D("%s: dev=%p fd=%d", __FUNCTION__, dev, handle->data[0]);
+ memset(&data->sensors, 0, sizeof(data->sensors));
+
+ for (i=0 ; i<MAX_NUM_SENSORS ; i++) {
+ data->sensors[i].acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
+ }
+ data->pendingSensors = 0;
+ data->timeStart = 0;
+ data->timeOffset = 0;
+
+ data->events_fd = dup(handle->data[0]);
+ D("%s: dev=%p fd=%d (was %d)", __FUNCTION__, dev, data->events_fd, handle->data[0]);
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ return 0;
+}
+
+static int
+data__data_close(struct sensors_poll_device_t *dev)
+{
+ SensorPoll* data = (void*)dev;
+ D("%s: dev=%p", __FUNCTION__, dev);
+ if (data->events_fd >= 0) {
+ close(data->events_fd);
+ data->events_fd = -1;
+ }
+ return 0;
+}
+
+static int
+pick_sensor(SensorPoll* data,
+ sensors_event_t* values)
+{
+ uint32_t mask = SUPPORTED_SENSORS;
+ while (mask) {
+ uint32_t i = 31 - __builtin_clz(mask);
+ mask &= ~(1<<i);
+ if (data->pendingSensors & (1<<i)) {
+ data->pendingSensors &= ~(1<<i);
+ *values = data->sensors[i];
+ values->sensor = i;
+ values->version = sizeof(*values);
+
+ D("%s: %d [%f, %f, %f]", __FUNCTION__,
+ i,
+ values->data[0],
+ values->data[1],
+ values->data[2]);
+ return i;
+ }
+ }
+ LOGE("No sensor to return!!! pendingSensors=%08x", data->pendingSensors);
+ // we may end-up in a busy loop, slow things down, just in case.
+ usleep(100000);
+ return -EINVAL;
+}
+
+static int
+data__poll(struct sensors_poll_device_t *dev, sensors_event_t* values)
+{
+ SensorPoll* data = (void*)dev;
+ int fd = data->events_fd;
+
+ D("%s: data=%p", __FUNCTION__, dev);
+
+ // there are pending sensors, returns them now...
+ if (data->pendingSensors) {
+ return pick_sensor(data, values);
+ }
+
+ // wait until we get a complete event for an enabled sensor
+ uint32_t new_sensors = 0;
+
+ while (1) {
+ /* read the next event */
+ char buff[256];
+ int len = qemud_channel_recv(data->events_fd, buff, sizeof buff-1);
+ float params[3];
+ int64_t event_time;
+
+ if (len < 0) {
+ E("%s: len=%d, errno=%d: %s", __FUNCTION__, len, errno, strerror(errno));
+ return -errno;
+ }
+
+ buff[len] = 0;
+
+ /* "wake" is sent from the emulator to exit this loop. */
+ if (!strcmp((const char*)data, "wake")) {
+ return 0x7FFFFFFF;
+ }
+
+ /* "acceleration:<x>:<y>:<z>" corresponds to an acceleration event */
+ if (sscanf(buff, "acceleration:%g:%g:%g", params+0, params+1, params+2) == 3) {
+ new_sensors |= SENSORS_ACCELERATION;
+ data->sensors[ID_ACCELERATION].acceleration.x = params[0];
+ data->sensors[ID_ACCELERATION].acceleration.y = params[1];
+ data->sensors[ID_ACCELERATION].acceleration.z = params[2];
+ continue;
+ }
+
+ /* "orientation:<azimuth>:<pitch>:<roll>" is sent when orientation changes */
+ if (sscanf(buff, "orientation:%g:%g:%g", params+0, params+1, params+2) == 3) {
+ new_sensors |= SENSORS_ORIENTATION;
+ data->sensors[ID_ORIENTATION].orientation.azimuth = params[0];
+ data->sensors[ID_ORIENTATION].orientation.pitch = params[1];
+ data->sensors[ID_ORIENTATION].orientation.roll = params[2];
+ continue;
+ }
+
+ /* "magnetic:<x>:<y>:<z>" is sent for the params of the magnetic field */
+ if (sscanf(buff, "magnetic:%g:%g:%g", params+0, params+1, params+2) == 3) {
+ new_sensors |= SENSORS_MAGNETIC_FIELD;
+ data->sensors[ID_MAGNETIC_FIELD].magnetic.x = params[0];
+ data->sensors[ID_MAGNETIC_FIELD].magnetic.y = params[1];
+ data->sensors[ID_MAGNETIC_FIELD].magnetic.z = params[2];
+ continue;
+ }
+
+ /* "temperature:<celsius>" */
+ if (sscanf(buff, "temperature:%g", params+0) == 2) {
+ new_sensors |= SENSORS_TEMPERATURE;
+ data->sensors[ID_TEMPERATURE].temperature = params[0];
+ continue;
+ }
+
+ /* "proximity:<value>" */
+ if (sscanf(buff, "proximity:%g", params+0) == 1) {
+ new_sensors |= SENSORS_PROXIMITY;
+ data->sensors[ID_PROXIMITY].distance = params[0];
+ continue;
+ }
+
+ /* "sync:<time>" is sent after a series of sensor events.
+ * where 'time' is expressed in micro-seconds and corresponds
+ * to the VM time when the real poll occured.
+ */
+ if (sscanf(buff, "sync:%lld", &event_time) == 1) {
+ if (new_sensors) {
+ data->pendingSensors = new_sensors;
+ int64_t t = event_time * 1000LL; /* convert to nano-seconds */
+
+ /* use the time at the first sync: as the base for later
+ * time values */
+ if (data->timeStart == 0) {
+ data->timeStart = data__now_ns();
+ data->timeOffset = data->timeStart - t;
+ }
+ t += data->timeOffset;
+
+ while (new_sensors) {
+ uint32_t i = 31 - __builtin_clz(new_sensors);
+ new_sensors &= ~(1<<i);
+ data->sensors[i].timestamp = t;
+ }
+ return pick_sensor(data, values);
+ } else {
+ D("huh ? sync without any sensor data ?");
+ }
+ continue;
+ }
+ D("huh ? unsupported command");
+ }
+ return -1;
+}
+
+static int
+data__close(struct hw_device_t *dev)
+{
+ SensorPoll* data = (SensorPoll*)dev;
+ if (data) {
+ if (data->events_fd >= 0) {
+ //LOGD("(device close) about to close fd=%d", data->events_fd);
+ close(data->events_fd);
+ }
+ free(data);
+ }
+ return 0;
+}
+
+/** SENSORS POLL DEVICE FUNCTIONS **/
+
+static int poll__close(struct hw_device_t* dev)
+{
+ SensorPoll* ctl = (void*)dev;
+ close(ctl->fd);
+ if (ctl->fd >= 0) {
+ close(ctl->fd);
+ }
+ if (ctl->events_fd >= 0) {
+ close(ctl->events_fd);
+ }
+ free(ctl);
+ return 0;
+}
+
+static int poll__poll(struct sensors_poll_device_t *dev,
+ sensors_event_t* data, int count)
+{
+ SensorPoll* datadev = (void*)dev;
+ int ret;
+ int i;
+ D("%s: dev=%p data=%p count=%d ", __FUNCTION__, dev, data, count);
+
+ for (i = 0; i < count; i++) {
+ ret = data__poll(dev, data);
+ data++;
+ if (ret > MAX_NUM_SENSORS || ret < 0) {
+ return i;
+ }
+ if (!datadev->pendingSensors) {
+ return i + 1;
+ }
+ }
+ return count;
+}
+
+static int poll__activate(struct sensors_poll_device_t *dev,
+ int handle, int enabled)
+{
+ int ret;
+ native_handle_t* hdl;
+ SensorPoll* ctl = (void*)dev;
+ D("%s: dev=%p handle=%x enable=%d ", __FUNCTION__, dev, handle, enabled);
+ if (ctl->fd < 0) {
+ D("%s: OPEN CTRL and DATA ", __FUNCTION__);
+ hdl = control__open_data_source(dev);
+ ret = data__data_open(dev,hdl);
+ }
+ ret = control__activate(dev, handle, enabled);
+ return ret;
+}
+
+static int poll__setDelay(struct sensors_poll_device_t *dev,
+ int handle, int64_t ns)
+{
+ // TODO
+ return 0;
+}
+
+/** MODULE REGISTRATION SUPPORT
+ **
+ ** This is required so that hardware/libhardware/hardware.c
+ ** will dlopen() this library appropriately.
+ **/
+
+/*
+ * the following is the list of all supported sensors.
+ * this table is used to build sSensorList declared below
+ * according to which hardware sensors are reported as
+ * available from the emulator (see get_sensors_list below)
+ *
+ * note: numerical values for maxRange/resolution/power were
+ * taken from the reference AK8976A implementation
+ */
+static const struct sensor_t sSensorListInit[] = {
+ { .name = "Goldfish 3-axis Accelerometer",
+ .vendor = "The Android Open Source Project",
+ .version = 1,
+ .handle = ID_ACCELERATION,
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .maxRange = 2.8f,
+ .resolution = 1.0f/4032.0f,
+ .power = 3.0f,
+ .reserved = {}
+ },
+
+ { .name = "Goldfish 3-axis Magnetic field sensor",
+ .vendor = "The Android Open Source Project",
+ .version = 1,
+ .handle = ID_MAGNETIC_FIELD,
+ .type = SENSOR_TYPE_MAGNETIC_FIELD,
+ .maxRange = 2000.0f,
+ .resolution = 1.0f,
+ .power = 6.7f,
+ .reserved = {}
+ },
+
+ { .name = "Goldfish Orientation sensor",
+ .vendor = "The Android Open Source Project",
+ .version = 1,
+ .handle = ID_ORIENTATION,
+ .type = SENSOR_TYPE_ORIENTATION,
+ .maxRange = 360.0f,
+ .resolution = 1.0f,
+ .power = 9.7f,
+ .reserved = {}
+ },
+
+ { .name = "Goldfish Temperature sensor",
+ .vendor = "The Android Open Source Project",
+ .version = 1,
+ .handle = ID_TEMPERATURE,
+ .type = SENSOR_TYPE_TEMPERATURE,
+ .maxRange = 80.0f,
+ .resolution = 1.0f,
+ .power = 0.0f,
+ .reserved = {}
+ },
+
+ { .name = "Goldfish Proximity sensor",
+ .vendor = "The Android Open Source Project",
+ .version = 1,
+ .handle = ID_PROXIMITY,
+ .type = SENSOR_TYPE_PROXIMITY,
+ .maxRange = 1.0f,
+ .resolution = 1.0f,
+ .power = 20.0f,
+ .reserved = {}
+ },
+};
+
+static struct sensor_t sSensorList[MAX_NUM_SENSORS];
+
+static int sensors__get_sensors_list(struct sensors_module_t* module,
+ struct sensor_t const** list)
+{
+ int fd = qemud_channel_open(SENSORS_SERVICE_NAME);
+ char buffer[12];
+ int mask, nn, count;
+
+ int ret;
+ if (fd < 0) {
+ E("%s: no qemud connection", __FUNCTION__);
+ return 0;
+ }
+ ret = qemud_channel_send(fd, "list-sensors", -1);
+ if (ret < 0) {
+ E("%s: could not query sensor list: %s", __FUNCTION__,
+ strerror(errno));
+ close(fd);
+ return 0;
+ }
+ ret = qemud_channel_recv(fd, buffer, sizeof buffer-1);
+ if (ret < 0) {
+ E("%s: could not receive sensor list: %s", __FUNCTION__,
+ strerror(errno));
+ close(fd);
+ return 0;
+ }
+ buffer[ret] = 0;
+ close(fd);
+
+ /* the result is a integer used as a mask for available sensors */
+ mask = atoi(buffer);
+ count = 0;
+ for (nn = 0; nn < MAX_NUM_SENSORS; nn++) {
+ if (((1 << nn) & mask) == 0)
+ continue;
+
+ sSensorList[count++] = sSensorListInit[nn];
+ }
+ D("%s: returned %d sensors (mask=%d)", __FUNCTION__, count, mask);
+ *list = sSensorList;
+ return count;
+}
+
+
+static int
+open_sensors(const struct hw_module_t* module,
+ const char* name,
+ struct hw_device_t* *device)
+{
+ int status = -EINVAL;
+
+ D("%s: name=%s", __FUNCTION__, name);
+
+ if (!strcmp(name, SENSORS_HARDWARE_POLL)) {
+ SensorPoll *dev = malloc(sizeof(*dev));
+
+ memset(dev, 0, sizeof(*dev));
+
+ dev->device.common.tag = HARDWARE_DEVICE_TAG;
+ dev->device.common.version = 0;
+ dev->device.common.module = (struct hw_module_t*) module;
+ dev->device.common.close = poll__close;
+ dev->device.poll = poll__poll;
+ dev->device.activate = poll__activate;
+ dev->device.setDelay = poll__setDelay;
+ dev->events_fd = -1;
+ dev->fd = -1;
+
+ *device = &dev->device.common;
+ status = 0;
+ }
+ return status;
+}
+
+
+static struct hw_module_methods_t sensors_module_methods = {
+ .open = open_sensors
+};
+
+const struct sensors_module_t HAL_MODULE_INFO_SYM = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = SENSORS_HARDWARE_MODULE_ID,
+ .name = "Goldfish SENSORS Module",
+ .author = "The Android Open Source Project",
+ .methods = &sensors_module_methods,
+ },
+ .get_sensors_list = sensors__get_sensors_list
+};
diff --git a/tools/monkeyrunner/Android.mk b/tools/monkeyrunner/Android.mk
deleted file mode 100644
index d15c67e..0000000
--- a/tools/monkeyrunner/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-MONKEYRUNNER_LOCAL_DIR := $(call my-dir)
-include $(MONKEYRUNNER_LOCAL_DIR)/etc/Android.mk
-include $(MONKEYRUNNER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/monkeyrunner/MODULE_LICENSE_APACHE2 b/tools/monkeyrunner/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/tools/monkeyrunner/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/monkeyrunner/NOTICE b/tools/monkeyrunner/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/tools/monkeyrunner/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/tools/monkeyrunner/etc/manifest.txt b/tools/monkeyrunner/etc/manifest.txt
deleted file mode 100644
index 288be5f..0000000
--- a/tools/monkeyrunner/etc/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.monkeyrunner.MonkeyRunner
diff --git a/tools/monkeyrunner/etc/monkeyrunner b/tools/monkeyrunner/etc/monkeyrunner
deleted file mode 100755
index 364be2a..0000000
--- a/tools/monkeyrunner/etc/monkeyrunner
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/sh
-# Copyright 2005-2007, 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=monkeyrunner.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/tools/lib
- libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/framework
- libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- echo `basename "$prog"`": can't find $jarfile"
- exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
- # add this in for debugging
- java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
- shift 1
-else
- java_debug=
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
- jarpath=`cygpath -w "$frameworkdir/$jarfile"`
- progdir=`cygpath -w "$progdir"`
-else
- jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-# might need more memory, e.g. -Xmx128M
-exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.monkeyrunner.bindir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/monkeyrunner/src/Android.mk b/tools/monkeyrunner/src/Android.mk
deleted file mode 100644
index fb6b9c1..0000000
--- a/tools/monkeyrunner/src/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# Copyright (C) 2009 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.
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAR_MANIFEST := ../etc/manifest.txt
-LOCAL_JAVA_LIBRARIES := \
- ddmlib \
- jython \
- xmlwriter
-
-
-LOCAL_MODULE := monkeyrunner
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build ext.jar
-# ============================================================
-
-ext_dirs := ../../../../external/xmlwriter/src
-
-ext_src_files := $(call all-java-files-under,$(ext_dirs))
-
-# ==== the library =========================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(ext_src_files)
-
-LOCAL_NO_STANDARD_LIBRARIES := true
-#LOCAL_JAVA_LIBRARIES := core
-#LOCAL_STATIC_JAVA_LIBRARIES := libgoogleclient
-
-LOCAL_MODULE := xmlwriter
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRecorder.java b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRecorder.java
deleted file mode 100644
index f06eafd..0000000
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRecorder.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2009 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.android.monkeyrunner;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import org.jheer.XMLWriter;
-
-/**
- * MonkeyRecorder is a host side class that records the output of scripts that are run.
- * It creates a unique directory, puts in an xml file that records each cmd and result.
- * It stores every screenshot in this directory.
- * When finished, it zips this all up.
- *
- * Calling Sequence:
- * mr = new MonkeyRecorder(scriptName);
- * mr.startCommand();
- * [mr.addAttribute(name, value);]
- * ...
- * [mr.addInput(cmd);]
- * [mr.addResults(result, filename);] // filename = "" if no screenshot
- * mr.endCommand();
- * mr.addComment(comment);
- * mr.startCommand();
- * ...
- * mr.endCommand();
- * ...
- * mr.close();
- *
- * With MonkeyRunner this should output an xml file, <script_name>-yyyyMMdd-HH:mm:ss.xml, into the
- * directory out/<script_name>-yyyyMMdd-HH:mm:ss with the contents like:
- *
- * <?xml version="1.0" encoding='UTF-8'?>
- * <!-- Monkey Script Results -->
- * <script_run script_name="filename" monkeyRunnerVersion="0.2">
- * <!-- Device specific variables -->
- * <device_var var_name="name" var_value="value" />
- * <device_var name="build.display" value="opal-userdebug 1.6 DRC79 14207 test-keys"/>
- * ...
- * <!-- Script commands -->
- * <command>
- * dateTime="20090921-17:08:43"
- * <input cmd="Pressing: menu"/>
- * <response result="OK" dateTime="20090921-17:08:43"/>
- * </command>
- * ...
- * <command>
- * dateTime="20090921-17:09:44"
- * <input cmd="grabscreen"/>
- * <response result="OK" dateTime="20090921-17:09:45" screenshot="home_screen-20090921-17:09:45.png"/>
- * </command>
- * ...
- * </script_run>
- *
- * And then zip it up with all the screenshots in the file: <script_name>-yyyyMMdd-HH:mm:ss.zip.
- */
-
-public class MonkeyRecorder {
-
- // xml file to store output results in
- private static String mXmlFilename;
- private static FileWriter mXmlFile;
- private static XMLWriter mXmlWriter;
-
- // unique subdirectory to put results in (screenshots and xml file)
- private static String mDirname;
- private static List<String> mScreenShotNames = new ArrayList<String>();
-
- // where we store all the results for all the script runs
- private static final String ROOT_DIR = "out";
-
- // for getting the date and time in now()
- private static final SimpleDateFormat SIMPLE_DATE_TIME_FORMAT =
- new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
-
- /**
- * Create a new MonkeyRecorder that records commands and zips up screenshots for submittal
- *
- * @param scriptName filepath of the monkey script we are running
- */
- public MonkeyRecorder(String scriptName, String version) throws IOException {
- // Create directory structure to store xml file, images and zips
- File scriptFile = new File(scriptName);
- scriptName = scriptFile.getName(); // Get rid of path
- mDirname = ROOT_DIR + "/" + stripType(scriptName) + "-" + now();
- new File(mDirname).mkdirs();
-
- // Initialize xml file
- mXmlFilename = stampFilename(stripType(scriptName) + ".xml");
- initXmlFile(scriptName, version);
- }
-
- // Get the current date and time in a simple string format (used for timestamping filenames)
- private static String now() {
- return SIMPLE_DATE_TIME_FORMAT.format(Calendar.getInstance().getTime());
- }
-
- /**
- * Initialize the xml file writer
- *
- * @param scriptName filename (not path) of the monkey script, stored as attribute in the xml file
- * @param version of the monkey runner test system
- */
- private static void initXmlFile(String scriptName, String version) throws IOException {
- String[] names = new String[] { "script_name", "monkeyRunnerVersion" };
- String[] values = new String[] { scriptName, version };
- mXmlFile = new FileWriter(mDirname + "/" + mXmlFilename);
- mXmlWriter = new XMLWriter(mXmlFile);
- mXmlWriter.begin();
- mXmlWriter.comment("Monkey Script Results");
- mXmlWriter.start("script_run", names, values, names.length);
- }
-
- /**
- * Add a comment to the xml file.
- *
- * @param comment comment to add to the xml file
- */
- public static void addComment(String comment) throws IOException {
- mXmlWriter.comment(comment);
- }
-
- /**
- * Begin writing a command xml element
- */
- public static void startCommand() throws IOException {
- mXmlWriter.start("command", "dateTime", now());
- }
-
- /**
- * Write a command name attribute in a command xml element.
- * It's add as a sinlge script command could be multiple monkey commands.
- *
- * @param cmd command sent to the monkey
- */
- public static void addInput(String cmd) throws IOException {
- String name = "cmd";
- String value = cmd;
- mXmlWriter.tag("input", name, value);
- }
-
- /**
- * Write a response xml element in a command.
- * Attributes include the monkey result, datetime, and possibly screenshot filename
- *
- * @param result response of the monkey to the command
- * @param filename filename of the screen shot (or other file to be included)
- */
- public static void addResult(String result, String filename) throws IOException {
- int num_args = 2;
- String[] names = new String[3];
- String[] values = new String[3];
- names[0] = "result";
- values[0] = result;
- names[1] = "dateTime";
- values[1] = now();
- if (filename.length() != 0) {
- names[2] = "screenshot";
- values[2] = stampFilename(filename);
- addScreenShot(filename);
- num_args = 3;
- }
- mXmlWriter.tag("response", names, values, num_args);
- }
-
- /**
- * Add an attribut to an open xml element. name="escaped_value"
- *
- * @param name name of the attribute
- * @param value value of the attribute
- */
- public static void addAttribute(String name, String value) throws IOException {
- mXmlWriter.addAttribute(name, value);
- }
-
- /**
- * Add an xml device variable element. name="escaped_value"
- *
- * @param name name of the variable
- * @param value value of the variable
- */
- public static void addDeviceVar(String name, String value) throws IOException {
- String[] names = {"name", "value"};
- String[] values = {name, value};
- mXmlWriter.tag("device_var", names, values, names.length);
- }
-
- /**
- * Move the screenshot to storage and remember you did it so it can be zipped up later.
- *
- * @param filename file name of the screenshot to be stored (Not path name)
- */
- private static void addScreenShot(String filename) {
- File file = new File(filename);
- String screenShotName = stampFilename(filename);
- file.renameTo(new File(mDirname, screenShotName));
- mScreenShotNames.add(screenShotName);
- }
-
- /**
- * Finish writing a command xml element
- */
- public static void endCommand() throws IOException {
- mXmlWriter.end();
- }
-
- /**
- * Add datetime in front of filetype (the stuff after and including the last infamous '.')
- *
- * @param filename path of file to be stamped
- */
- private static String stampFilename(String filename) {
- //
- int typeIndex = filename.lastIndexOf('.');
- if (typeIndex == -1) {
- return filename + "-" + now();
- }
- return filename.substring(0, typeIndex) + "-" + now() + filename.substring(typeIndex);
- }
-
- /**
- * Strip out the file type (the stuff after and including the last infamous '.')
- *
- * @param filename path of file to be stripped of type information
- */
- private static String stripType(String filename) {
- //
- int typeIndex = filename.lastIndexOf('.');
- if (typeIndex == -1)
- return filename;
- return filename.substring(0, typeIndex);
- }
-
- /**
- * Close the monkeyRecorder by closing the xml file and zipping it up with the screenshots.
- *
- * @param filename path of file to be stripped of type information
- */
- public static void close() throws IOException {
- // zip up xml file and screenshots into ROOT_DIR.
- byte[] buf = new byte[1024];
- String zipFileName = mXmlFilename + ".zip";
- endCommand();
- mXmlFile.close();
- FileOutputStream zipFile = new FileOutputStream(ROOT_DIR + "/" + zipFileName);
- ZipOutputStream out = new ZipOutputStream(zipFile);
-
- // add the xml file
- addFileToZip(out, mDirname + "/" + mXmlFilename, buf);
-
- // Add the screenshots
- for (String filename : mScreenShotNames) {
- addFileToZip(out, mDirname + "/" + filename, buf);
- }
- out.close();
- }
-
- /**
- * Helper function to zip up a file into an open zip archive.
- *
- * @param zip the stream of the zip archive
- * @param filepath the filepath of the file to be added to the zip archive
- * @param buf storage place to stage reads of file before zipping
- */
- private static void addFileToZip(ZipOutputStream zip, String filepath, byte[] buf) throws IOException {
- FileInputStream in = new FileInputStream(filepath);
- zip.putNextEntry(new ZipEntry(filepath));
- int len;
- while ((len = in.read(buf)) > 0) {
- zip.write(buf, 0, len);
- }
- zip.closeEntry();
- in.close();
- }
-}
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunner.java b/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunner.java
deleted file mode 100644
index 4734ba1..0000000
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/MonkeyRunner.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright (C) 2009 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.android.monkeyrunner;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.NullOutputReceiver;
-import com.android.ddmlib.RawImage;
-import com.android.ddmlib.Log.ILogOutput;
-import com.android.ddmlib.Log.LogLevel;
-
-import java.awt.image.BufferedImage;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.imageio.ImageIO;
-
-/**
- * MonkeyRunner is a host side application to control a monkey instance on a
- * device. MonkeyRunner provides some useful helper functions to control the
- * device as well as various other methods to help script tests.
- */
-public class MonkeyRunner {
-
- static String monkeyServer = "127.0.0.1";
- static int monkeyPort = 1080;
- static Socket monkeySocket = null;
-
- static IDevice monkeyDevice;
-
- static BufferedReader monkeyReader;
- static BufferedWriter monkeyWriter;
- static String monkeyResponse;
-
- static MonkeyRecorder monkeyRecorder;
-
- static String scriptName = null;
-
- // Obtain a suitable logger.
- private static Logger logger = Logger.getLogger("com.android.monkeyrunner");
-
- // delay between key events
- final static int KEY_INPUT_DELAY = 1000;
-
- // version of monkey runner
- final static String monkeyRunnerVersion = "0.4";
-
- // TODO: interface cmd; class xml tags; fix logger; test class/script
-
- public static void main(String[] args) throws IOException {
-
- // haven't figure out how to get below INFO...bad parent. Pass -v INFO to turn on logging
- logger.setLevel(Level.parse("WARNING"));
- processOptions(args);
-
- logger.info("initAdb");
- initAdbConnection();
- logger.info("openMonkeyConnection");
- openMonkeyConnection();
-
- logger.info("start_script");
- start_script();
-
- logger.info("ScriptRunner.run");
- ScriptRunner.run(scriptName);
-
- logger.info("end_script");
- end_script();
- logger.info("closeMonkeyConnection");
- closeMonkeyConnection();
- }
-
- /**
- * Initialize an adb session with a device connected to the host
- *
- */
- public static void initAdbConnection() {
- String adbLocation = "adb";
- boolean device = false;
- boolean emulator = false;
- String serial = null;
-
- AndroidDebugBridge.init(false /* debugger support */);
-
- try {
- AndroidDebugBridge bridge = AndroidDebugBridge.createBridge(
- adbLocation, true /* forceNewBridge */);
-
- // we can't just ask for the device list right away, as the internal thread getting
- // them from ADB may not be done getting the first list.
- // Since we don't really want getDevices() to be blocking, we wait here manually.
- int count = 0;
- while (bridge.hasInitialDeviceList() == false) {
- try {
- Thread.sleep(100);
- count++;
- } catch (InterruptedException e) {
- // pass
- }
-
- // let's not wait > 10 sec.
- if (count > 100) {
- System.err.println("Timeout getting device list!");
- return;
- }
- }
-
- // now get the devices
- IDevice[] devices = bridge.getDevices();
-
- if (devices.length == 0) {
- printAndExit("No devices found!", true /* terminate */);
- }
-
- monkeyDevice = null;
-
- if (emulator || device) {
- for (IDevice d : devices) {
- // this test works because emulator and device can't both be true at the same
- // time.
- if (d.isEmulator() == emulator) {
- // if we already found a valid target, we print an error and return.
- if (monkeyDevice != null) {
- if (emulator) {
- printAndExit("Error: more than one emulator launched!",
- true /* terminate */);
- } else {
- printAndExit("Error: more than one device connected!",true /* terminate */);
- }
- }
- monkeyDevice = d;
- }
- }
- } else if (serial != null) {
- for (IDevice d : devices) {
- if (serial.equals(d.getSerialNumber())) {
- monkeyDevice = d;
- break;
- }
- }
- } else {
- if (devices.length > 1) {
- printAndExit("Error: more than one emulator or device available!",
- true /* terminate */);
- }
- monkeyDevice = devices[0];
- }
-
- monkeyDevice.createForward(monkeyPort, monkeyPort);
- String command = "monkey --port " + monkeyPort;
- monkeyDevice.executeShellCommand(command, new NullOutputReceiver());
-
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Open a tcp session over adb with the device to communicate monkey commands
- */
- public static void openMonkeyConnection() {
- try {
- InetAddress addr = InetAddress.getByName(monkeyServer);
- monkeySocket = new Socket(addr, monkeyPort);
- monkeyWriter = new BufferedWriter(new OutputStreamWriter(monkeySocket.getOutputStream()));
- monkeyReader = new BufferedReader(new InputStreamReader(monkeySocket.getInputStream()));
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Close tcp session with the monkey on the device
- *
- */
- public static void closeMonkeyConnection() {
- try {
- monkeyReader.close();
- monkeyWriter.close();
- monkeySocket.close();
- AndroidDebugBridge.terminate();
- } catch(IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * This is a house cleaning routine to run before starting a script. Puts
- * the device in a known state and starts recording interesting info.
- */
- public static void start_script() throws IOException {
- press("menu", false);
- press("menu", false);
- press("home", false);
-
- // Start recording the script output, might want md5 signature of file for completeness
- monkeyRecorder = new MonkeyRecorder(scriptName, monkeyRunnerVersion);
-
- // Record what device we are running on
- addDeviceVars();
- monkeyRecorder.addComment("Script commands");
- }
-
- /**
- * This is a house cleaning routine to run after finishing a script.
- * Puts the monkey server in a known state and closes the recording.
- */
- public static void end_script() throws IOException {
- String command = "done";
- sendMonkeyEvent(command, false, false);
-
- // Stop the recording and zip up the results
- monkeyRecorder.close();
- }
-
- /** This is a method for scripts to launch an activity on the device
- *
- * @param name The name of the activity to launch
- */
- public static void launch_activity(String name) throws IOException {
- System.out.println("Launching: " + name);
- recordCommand("Launching: " + name);
- monkeyDevice.executeShellCommand("am start -a android.intent.action.MAIN -n "
- + name, new NullOutputReceiver());
- // void return, so no response given, just close the command element in the xml file.
- monkeyRecorder.endCommand();
- }
-
- /**
- * Grabs the current state of the screen stores it as a png
- *
- * @param tag filename or tag descriptor of the screenshot
- */
- public static void grabscreen(String tag) throws IOException {
- tag += ".png";
-
- try {
- Thread.sleep(1000);
- getDeviceImage(monkeyDevice, tag, false);
- } catch (InterruptedException e) {
- }
- }
-
- /**
- * Sleeper method for script to call
- *
- * @param msec msecs to sleep for
- */
- public static void sleep(int msec) throws IOException {
- try {
- recordCommand("sleep: " + msec);
- Thread.sleep(msec);
- recordResponse("OK");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Tap function for scripts to call at a particular x and y location
- *
- * @param x x-coordinate
- * @param y y-coordinate
- */
- public static boolean tap(int x, int y) throws IOException {
- String command = "tap " + x + " " + y;
- boolean result = sendMonkeyEvent(command);
- return result;
- }
-
- /**
- * Press function for scripts to call on a particular button or key
- *
- * @param key key to press
- */
- public static boolean press(String key) throws IOException {
- return press(key, true);
- }
-
- /**
- * Press function for scripts to call on a particular button or key
- *
- * @param key key to press
- * @param print whether to send output to user
- */
- private static boolean press(String key, boolean print) throws IOException {
- String command = "press " + key;
- boolean result = sendMonkeyEvent(command, print, true);
- return result;
- }
-
- /**
- * dpad down function
- */
- public static boolean down() throws IOException {
- return press("dpad_down");
- }
-
- /**
- * dpad up function
- */
- public static boolean up() throws IOException {
- return press("dpad_up");
- }
-
- /**
- * Function to type text on the device
- *
- * @param text text to type
- */
- public static boolean type(String text) throws IOException {
- boolean result = false;
- // text might have line ends, which signal new monkey command, so we have to eat and reissue
- String[] lines = text.split("[\\r\\n]+");
- for (String line: lines) {
- result = sendMonkeyEvent("type " + line + "\n");
- }
- // return last result. Should never fail..?
- return result;
- }
-
- /**
- * Function to get a static variable from the device
- *
- * @param name name of static variable to get
- */
- public static boolean getvar(String name) throws IOException {
- return sendMonkeyEvent("getvar " + name + "\n");
- }
-
- /**
- * Function to get the list of static variables from the device
- */
- public static boolean listvar() throws IOException {
- return sendMonkeyEvent("listvar \n");
- }
-
- /**
- * This function is the communication bridge between the host and the device.
- * It sends monkey events and waits for responses over the adb tcp socket.
- * This version if for all scripted events so that they get recorded and reported to user.
- *
- * @param command the monkey command to send to the device
- */
- private static boolean sendMonkeyEvent(String command) throws IOException {
- return sendMonkeyEvent(command, true, true);
- }
-
- /**
- * This function allows the communication bridge between the host and the device
- * to be invisible to the script for internal needs.
- * It splits a command into monkey events and waits for responses for each over an adb tcp socket.
- * Returns on an error, else continues and sets up last response.
- *
- * @param command the monkey command to send to the device
- * @param print whether to print out the responses to the user
- * @param record whether to put the command in the xml file that stores test outputs
- */
- private static boolean sendMonkeyEvent(String command, Boolean print, Boolean record) throws IOException {
- command = command.trim();
- if (print)
- System.out.println("MonkeyCommand: " + command);
- if (record)
- recordCommand(command);
- logger.info("Monkey Command: " + command + ".");
-
- // send a single command and get the response
- monkeyWriter.write(command + "\n");
- monkeyWriter.flush();
- monkeyResponse = monkeyReader.readLine();
-
- if(monkeyResponse != null) {
- // if a command returns with a response
- if (print)
- System.out.println("MonkeyServer: " + monkeyResponse);
- if (record)
- recordResponse(monkeyResponse);
- logger.info("Monkey Response: " + monkeyResponse + ".");
-
- // return on error
- if (monkeyResponse.startsWith("ERROR"))
- return false;
-
- // return on ok
- if(monkeyResponse.startsWith("OK"))
- return true;
-
- // return on something else?
- return false;
- }
- // didn't get a response...
- if (print)
- System.out.println("MonkeyServer: ??no response");
- if (record)
- recordResponse("??no response");
- logger.info("Monkey Response: ??no response.");
-
- //return on no response
- return false;
- }
-
- /**
- * Record the command in the xml file
- *
- * @param command the command sent to the monkey server
- */
- private static void recordCommand(String command) throws IOException {
- if (monkeyRecorder != null) { // don't record setup junk
- monkeyRecorder.startCommand();
- monkeyRecorder.addInput(command);
- }
- }
-
- /**
- * Record the response in the xml file
- *
- * @param response the response sent by the monkey server
- */
- private static void recordResponse(String response) throws IOException {
- recordResponse(response, "");
- }
-
- /**
- * Record the response and the filename in the xml file, store the file (to be zipped up later)
- *
- * @param response the response sent by the monkey server
- * @param filename the filename of a file to be time stamped, recorded in the xml file and stored
- */
- private static void recordResponse(String response, String filename) throws IOException {
- if (monkeyRecorder != null) { // don't record setup junk
- monkeyRecorder.addResult(response, filename); // ignores file if filename empty
- monkeyRecorder.endCommand();
- }
- }
-
- /**
- * Add the device variables to the xml file in monkeyRecorder.
- * The results get added as device_var tags in the script_run tag
- */
- private static void addDeviceVars() throws IOException {
- monkeyRecorder.addComment("Device specific variables");
- sendMonkeyEvent("listvar \n", false, false);
- if (monkeyResponse.startsWith("OK:")) {
- // peel off "OK:" string and get the individual var names
- String[] varNames = monkeyResponse.substring(3).split("\\s+");
- // grab all the individual var values
- for (String name: varNames) {
- sendMonkeyEvent("getvar " + name, false, false);
- if(monkeyResponse != null) {
- if (monkeyResponse.startsWith("OK") ) {
- if (monkeyResponse.length() > 2) {
- monkeyRecorder.addDeviceVar(name, monkeyResponse.substring(3));
- } else {
- // only got OK - good variable but no value
- monkeyRecorder.addDeviceVar(name, "null");
- }
- } else {
- // error returned - couldn't get var value for name... include error return
- monkeyRecorder.addDeviceVar(name, monkeyResponse);
- }
- } else {
- // no monkeyResponse - bad variable with no value
- monkeyRecorder.addDeviceVar(name, "null");
- }
- }
- } else {
- // it's an error, can't find variable names...
- monkeyRecorder.addAttribute("listvar", monkeyResponse);
- }
- }
-
- /**
- * Process the command-line options
- *
- * @return Returns true if options were parsed with no apparent errors.
- */
- private static void processOptions(String[] args) {
- // parse command line parameters.
- int index = 0;
-
- do {
- String argument = args[index++];
-
- if ("-s".equals(argument)) {
- if(index == args.length) {
- printUsageAndQuit("Missing Server after -s");
- }
-
- monkeyServer = args[index++];
-
- } else if ("-p".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsageAndQuit("Missing Server port after -p");
- }
-
- monkeyPort = Integer.parseInt(args[index++]);
-
- } else if ("-v".equals(argument)) {
- // quick check on the next argument.
- if (index == args.length) {
- printUsageAndQuit("Missing Log Level after -v");
- }
-
- Level level = Level.parse(args[index++]);
- logger.setLevel(level);
- level = logger.getLevel();
- System.out.println("Log level set to: " + level + "(" + level.intValue() + ").");
- System.out.println("Warning: Log levels below INFO(800) not working currently... parent issues");
-
- } else if (argument.startsWith("-")) {
- // we have an unrecognized argument.
- printUsageAndQuit("Unrecognized argument: " + argument + ".");
-
- monkeyPort = Integer.parseInt(args[index++]);
-
- } else {
- // get the filepath of the script to run. This will be the last undashed argument.
- scriptName = argument;
- }
- } while (index < args.length);
- }
-
- /*
- * Grab an image from an ADB-connected device.
- */
- private static void getDeviceImage(IDevice device, String filepath, boolean landscape)
- throws IOException {
- RawImage rawImage;
- recordCommand("grabscreen");
- System.out.println("Grabbing Screeshot: " + filepath + ".");
-
- try {
- rawImage = device.getScreenshot();
- }
- catch (IOException ioe) {
- recordResponse("No frame buffer", "");
- printAndExit("Unable to get frame buffer: " + ioe.getMessage(), true /* terminate */);
- return;
- }
-
- // device/adb not available?
- if (rawImage == null) {
- recordResponse("No image", "");
- return;
- }
-
- assert rawImage.bpp == 16;
-
- BufferedImage image;
-
- logger.info("Raw Image - height: " + rawImage.height + ", width: " + rawImage.width);
-
- if (landscape) {
- // convert raw data to an Image
- image = new BufferedImage(rawImage.height, rawImage.width,
- BufferedImage.TYPE_INT_ARGB);
-
- byte[] buffer = rawImage.data;
- int index = 0;
- for (int y = 0 ; y < rawImage.height ; y++) {
- for (int x = 0 ; x < rawImage.width ; x++) {
-
- int value = buffer[index++] & 0x00FF;
- value |= (buffer[index++] << 8) & 0x0FF00;
-
- int r = ((value >> 11) & 0x01F) << 3;
- int g = ((value >> 5) & 0x03F) << 2;
- int b = ((value >> 0) & 0x01F) << 3;
-
- value = 0xFF << 24 | r << 16 | g << 8 | b;
-
- image.setRGB(y, rawImage.width - x - 1, value);
- }
- }
- } else {
- // convert raw data to an Image
- image = new BufferedImage(rawImage.width, rawImage.height,
- BufferedImage.TYPE_INT_ARGB);
-
- byte[] buffer = rawImage.data;
- int index = 0;
- for (int y = 0 ; y < rawImage.height ; y++) {
- for (int x = 0 ; x < rawImage.width ; x++) {
-
- int value = buffer[index++] & 0x00FF;
- value |= (buffer[index++] << 8) & 0x0FF00;
-
- int r = ((value >> 11) & 0x01F) << 3;
- int g = ((value >> 5) & 0x03F) << 2;
- int b = ((value >> 0) & 0x01F) << 3;
-
- value = 0xFF << 24 | r << 16 | g << 8 | b;
-
- image.setRGB(x, y, value);
- }
- }
- }
-
- if (!ImageIO.write(image, "png", new File(filepath))) {
- recordResponse("No png writer", "");
- throw new IOException("Failed to find png writer");
- }
- recordResponse("OK", filepath);
- }
-
- private static void printUsageAndQuit(String message) {
- // 80 cols marker: 01234567890123456789012345678901234567890123456789012345678901234567890123456789
- System.out.println(message);
- System.out.println("Usage: monkeyrunner [options] SCRIPT_FILE");
- System.out.println("");
- System.out.println(" -s MonkeyServer IP Address.");
- System.out.println(" -p MonkeyServer TCP Port.");
- System.out.println(" -v MonkeyServer Logging level (ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, OFF)");
- System.out.println("");
- System.out.println("");
-
- System.exit(1);
- }
-
- private static void printAndExit(String message, boolean terminate) {
- System.out.println(message);
- if (terminate) {
- AndroidDebugBridge.terminate();
- }
- System.exit(1);
- }
-}
diff --git a/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java b/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java
deleted file mode 100644
index 6a4405b..0000000
--- a/tools/monkeyrunner/src/com/android/monkeyrunner/ScriptRunner.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.android.monkeyrunner;
-
-import org.python.core.Py;
-import org.python.core.PyObject;
-import org.python.util.PythonInterpreter;
-import org.python.util.InteractiveConsole;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.lang.RuntimeException;
-import java.util.Properties;
-
-
-/**
- * Runs Jython based scripts.
- */
-public class ScriptRunner {
-
- /** The "this" scope object for scripts. */
- private final Object scope;
- private final String variable;
-
- /** Private constructor. */
- private ScriptRunner(Object scope, String variable) {
- this.scope = scope;
- this.variable = variable;
- }
-
- /** Creates a new instance for the given scope object. */
- public static ScriptRunner newInstance(Object scope, String variable) {
- return new ScriptRunner(scope, variable);
- }
-
- /**
- * Runs the specified Jython script. First runs the initialization script to
- * preload the appropriate client library version.
- */
- public static void run(String scriptfilename) {
- try {
- initPython();
- PythonInterpreter python = new PythonInterpreter();
-
- python.execfile(scriptfilename);
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
-
-
- /** Initialize the python interpreter. */
- private static void initPython() {
- Properties props = new Properties();
- // Default is 'message' which displays sys-package-mgr bloat
- // Choose one of error,warning,message,comment,debug
- props.setProperty("python.verbose", "error");
- props.setProperty("python.path", System.getProperty("java.class.path"));
- PythonInterpreter.initialize(System.getProperties(), props, new String[] {""});
- }
-
- /**
- * Create and run a console using a new python interpreter for the test
- * associated with this instance.
- */
- public void console() throws IOException {
- initPython();
- InteractiveConsole python = new InteractiveConsole();
- initInterpreter(python, scope, variable);
- python.interact();
- }
-
- /**
- * Start an interactive python interpreter using the specified set of local
- * variables. Use this to interrupt a running test script with a prompt:
- *
- * @param locals
- */
- public static void console(PyObject locals) {
- initPython();
- InteractiveConsole python = new InteractiveConsole(locals);
- python.interact();
- }
-
- /**
- * Initialize a python interpreter.
- *
- * @param python
- * @param scope
- * @throws IOException
- */
- public static void initInterpreter(PythonInterpreter python, Object scope, String variable)
- throws IOException {
- // Store the current test case as the this variable
- python.set(variable, scope);
- }
-}