merge from eclair

This commit is contained in:
Jean-Baptiste Queru
2009-11-15 12:05:38 -08:00
3240 changed files with 153711 additions and 72942 deletions

View File

@@ -0,0 +1,13 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_JAVA_LIBRARIES :=
LOCAL_PACKAGE_NAME := BluetoothDebug
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)

View File

@@ -0,0 +1,38 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.bluetoothdebug" >
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application android:label="Bluetooth Debug" >
<receiver android:name="DebugReceiver">
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
<action android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
<action android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
<action android:name="android.bluetooth.adapter.action.DISCOVERY_FINISHED" />
<action android:name="android.bluetooth.adapter.action.LOCAL_NAME_CHANGED" />
<action android:name="android.bluetooth.device.action.FOUND" />
<action android:name="android.bluetooth.device.action.DISAPPEARED" />
<action android:name="android.bluetooth.device.action.CLASS_CHANGED" />
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
<action android:name="android.bluetooth.device.action.NAME_CHANGED" />
<action android:name="android.bluetooth.device.action.BOND_STATE_CHANGED" />
<action android:name="android.bluetooth.device.action.NAME_FAILED" />
<action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
<action android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
<action android:name="android.bluetooth.device.action.UUID" />
<action android:name="android.bluetooth.headset.action.STATE_CHANGED" />
<action android:name="android.bluetooth.headset.action.AUDIO_STATE_CHANGED" />
<action android:name="android.bluetooth.a2dp.action.SINK_STATE_CHANGED" />
<action android:name="android.bluetooth.devicepicker.action.LAUNCH" />
<action android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
</intent-filter>
</receiver>
</application>
</manifest>

190
apps/BluetoothDebug/NOTICE Normal file
View File

@@ -0,0 +1,190 @@
Copyright (c) 2005-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.
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

View File

@@ -0,0 +1,65 @@
/*
* Copyright 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.bluetoothdebug;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevicePicker;
import android.bluetooth.BluetoothHeadset;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
/**
* Prints Bluetooth intents to logcat. For example:
* BTDEBUG : a.b.device.a.FOUND
* BTDEBUG : a.b.device.e.DEVICE = 00:18:13:F2:CC:33
* BTDEBUG : a.b.device.e.RSSI = -35
* BTDEBUG : a.b.device.e.CLASS = 200404
* BTDEBUG : a.b.adapter.a.DISCOVERY_FINISHED
* BTDEBUG : a.b.device.a.BOND_STATE_CHANGED
* BTDEBUG : a.b.device.e.DEVICE = 00:18:13:F2:CC:33
* BTDEBUG : a.b.device.e.BOND_STATE = 11
* BTDEBUG : a.b.device.e.PREVIOUS_BOND_STATE = 10
*/
public class DebugReceiver extends BroadcastReceiver {
private static final String TAG = "BTDEBUG";
public void onReceive(Context context, Intent intent) {
Log.d(TAG, shorten(intent.getAction()));
Bundle bundle = intent.getExtras();
if (bundle == null) return;
for (String extra : bundle.keySet()) {
Log.d(TAG, "\t" + shorten(extra) + " = " + bundle.get(extra));
}
}
// shorten string to shorthand
// android.bluetooth.device.extra.DEVICE -> a.b.device.e.DEVICE
private static String shorten(String action) {
return action.replace("android", "a")
.replace("bluetooth", "b")
.replace("extra", "e")
.replace("action", "a");
}
}

5
apps/CustomLocale/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.classpath
.project
bin
default.properties
gen

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -21,7 +21,7 @@
android:paddingLeft="8dip"
android:paddingRight="8dip">
<TextView
android:layout_width="wrap_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/new_locale_label" />
<EditText

View File

@@ -289,7 +289,15 @@ public class CustomLocaleActivity extends ListActivity {
IActivityManager am = ActivityManagerNative.getDefault();
Configuration config = am.getConfiguration();
Locale loc = new Locale(locale);
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

View File

@@ -31,8 +31,7 @@ import android.widget.EditText;
* "en_US") via an intent with a "locale" extra string and a "select" extra
* boolean.
*/
public class NewLocaleDialog extends Activity
implements View.OnClickListener, View.OnKeyListener {
public class NewLocaleDialog extends Activity implements View.OnClickListener {
public static final String INTENT_EXTRA_LOCALE = "locale";
public static final String INTENT_EXTRA_SELECT = "select";
@@ -55,13 +54,9 @@ public class NewLocaleDialog extends Activity
mButtonAdd = (Button) findViewById(R.id.add);
mButtonAdd.setOnClickListener(this);
mButtonAdd.setEnabled(false);
mButtonAddSelect = (Button) findViewById(R.id.add_and_select);
mButtonAddSelect.setOnClickListener(this);
mButtonAddSelect.setEnabled(false);
mEditText.setOnKeyListener(this);
}
public void onClick(View v) {
@@ -79,15 +74,4 @@ public class NewLocaleDialog extends Activity
finish();
}
public boolean onKey(View v, int keyCode, KeyEvent event) {
boolean isEmpty = TextUtils.isEmpty(mEditText.getText());
if (isEmpty != mWasEmpty) {
mWasEmpty = isEmpty;
mButtonAdd.setEnabled(!isEmpty);
mButtonAddSelect.setEnabled(!isEmpty);
}
return false;
}
}

View File

@@ -31,6 +31,9 @@
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.ALL_SERVICES" />
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.YouTubeUser" />
<uses-permission android:name="com.google.android.googleapps.permission.ACCESS_GOOGLE_PASSWORD" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<application android:label="Dev Tools"
android:icon="@drawable/ic_launcher_devtools">
@@ -73,6 +76,22 @@
</intent-filter>
</activity>
<activity android:name="AccountsTester" android:label="AccountsTester"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.TEST" />
</intent-filter>
</activity>
<activity android:name="SyncAdapterDriver" android:label="Sync Tester"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.TEST" />
</intent-filter>
</activity>
<activity android:name="DataList">
</activity>
<activity android:name="Details">

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 Google Inc.
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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/accounts_tester_remove_account"
android:title="@string/accounts_tester_remove_account" />
<item android:id="@+id/accounts_tester_get_auth_token"
android:title="@string/accounts_tester_get_auth_token" />
<item android:id="@+id/accounts_tester_invalidate_auth_token"
android:title="@string/accounts_tester_invalidate_auth_token" />
<item android:id="@+id/accounts_tester_update_credentials"
android:title="@string/accounts_tester_update_credentials" />
<item android:id="@+id/accounts_tester_confirm_credentials"
android:title="@string/accounts_tester_confirm_credentials" />
</menu>

View File

@@ -0,0 +1,20 @@
<?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.
-->
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ListView android:id="@+id/accounts_tester_authenticators_list"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/accounts_tester_account_types_spinner_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_select_account_type"/>
<Spinner android:id="@+id/accounts_tester_account_types_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/accounts_tester_get_accounts_by_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_get_accounts_by_type"/>
<Button
android:id="@+id/accounts_tester_get_all_accounts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_get_all_accounts"/>
<Button android:id="@+id/accounts_tester_add_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_add_account"/>
<Button android:id="@+id/accounts_tester_edit_properties"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_edit_properties"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/accounts_tester_desiredFeatures"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_desired_features_label"/>
<EditText android:id="@+id/accounts_tester_desired_features"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minEms="15"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/accounts_tester_desiredFeatures"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_desired_authtokentype_label"/>
<EditText android:id="@+id/accounts_tester_desired_authtokentype"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minEms="15"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ListView android:id="@+id/accounts_tester_accounts_list"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2008 Esmertec AG.
* 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingTop="1dip"
android:paddingBottom="1dip"
android:paddingLeft="9dip"
android:paddingRight="9dip">
<ImageView android:id="@+id/accounts_tester_authenticator_icon"
android:paddingRight="9dip"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/accounts_tester_authenticator_label"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_gravity="center_horizontal|center_vertical" />
</LinearLayout>

View File

@@ -68,10 +68,17 @@
android:layout_alignParentLeft="true"
android:text="@string/development_settings_show_updates_text" />
<CheckBox android:id="@+id/compatibility_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/show_updates"
android:layout_alignParentLeft="true"
android:text="@string/development_settings_compatibility_mode_text" />
<Spinner android:id="@+id/max_procs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/show_updates"
android:layout_below="@id/compatibility_mode"
android:layout_alignParentLeft="true" />
<View android:id="@+id/separator2"

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/accounts_tester_get_auth_token_dialog_message"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="@string/accounts_tester_enter_auth_token_type" />
<EditText android:id="@+id/accounts_tester_auth_token_type"
android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minWidth="250dip"
android:scrollHorizontally="true"
android:capitalize="none"
android:autoText="false"/>
</LinearLayout>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 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="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="vertical"
android:gravity="fill" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingRight="6dip"
android:paddingLeft="6dip"
android:gravity="center_vertical" >
<ImageView android:id="@+id/icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="@android:dimen/app_icon_size"
android:layout_marginLeft="5dip"
android:layout_marginRight="11dip"
android:layout_gravity="center_vertical"
android:scaleType="fitCenter"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_marginBottom="2dip" />
<TextView android:id="@+id/description"
android:layout_marginTop="-4dip"
android:layout_gravity="center_vertical|left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="4dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,86 @@
<?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:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/sync_adapters_spinner_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22dip"
android:text="@string/sync_adapters_spinner_label"/>
<Spinner android:id="@+id/sync_adapters_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="52dip">
<Button
android:id="@+id/bind_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/bind_button"
android:onClick="initiateBind"
android:layout_weight="2"/>
<Button
android:id="@+id/unbind_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/unbind_button"
android:onClick="initiateUnbind"
android:layout_weight="2"/>
</LinearLayout>
<TextView android:id="@+id/bound_adapter_text_view"
android:layout_width="wrap_content"
android:textSize="20dip"
android:layout_height="wrap_content"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="52dip">
<Button
android:id="@+id/start_sync_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/start_sync_button"
android:onClick="startSyncSelected"
android:layout_weight="2"/>
<Button
android:id="@+id/cancel_sync_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/cancel_sync_button"
android:onClick="cancelSync"
android:layout_weight="2"/>
</LinearLayout>
<TextView android:id="@+id/status_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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.
*/
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="52dip"
android:ellipsize="marquee" />

View File

@@ -77,6 +77,9 @@
<string name="development_settings_always_finish_text">Immediately destroy activities</string>
<string name="development_settings_show_load_text">Show running processes</string>
<string name="development_settings_show_updates_text">Show screen updates</string>
<string name="development_settings_compatibility_mode_text">Disable compatibility mode</string>
<string name="development_settings_compatibility_mode_toast">Reboot required for
change to take effect.</string>
<string name="development_settings_enable_gl_text">Enable OpenGL ES (reboot needed)</string>
<string name="development_settings_allow_mock_location_text">Allow mock locations for testing</string>
<string name="development_settings_wait_for_debugger_text">Wait for debugger</string>
@@ -133,4 +136,44 @@
<string name="perm_list_header_text">Apps using permission </string>
<string name="source_uid_text">Source uid : </string>
<string name="shared_pkgs_text">Packages accessing via shared uid : </string>
<!-- AccountsTester -->
<string name="accounts_tester_app_name">Accounts Tester</string>
<string name="accounts_tester_get_accounts_by_type">Get By Type</string>
<string name="accounts_tester_get_all_accounts">Get All</string>
<string name="accounts_tester_add_account">Add</string>
<string name="accounts_tester_select_account_type">Select Account Type</string>
<string name="accounts_tester_process_name_header">Process Name:</string>
<string name="accounts_tester_remove_account">remove</string>
<string name="accounts_tester_get_auth_token">authenticate</string>
<string name="accounts_tester_invalidate_auth_token">invalidate token</string>
<string name="accounts_tester_account_context_menu_title">account operations</string>
<string name="accounts_tester_do_get_auth_token">Ok</string>
<string name="accounts_tester_enter_auth_token_type">Enter the authtoken type:</string>
<string name="accounts_tester_update_credentials">Update Credentials</string>
<string name="accounts_tester_confirm_credentials">Confirm Credentials</string>
<string name="accounts_tester_edit_properties">Properties</string>
<string name="accounts_tester_desired_authtokentype_label">authtoken type:</string>
<string name="accounts_tester_desired_features_label">features:</string>
<!-- SyncAdapterDriver -->
<string name="bind_button">bind</string>
<string name="unbind_button">unbind</string>
<string name="start_sync_button">start sync</string>
<string name="cancel_sync_button">cancel sync</string>
<string name="sync_adapters_spinner_label">Registered Sync Adapters:</string>
<string name="status_starting_sync_format">Starting a sync of account %s...</string>
<string name="status_remote_exception_while_starting_sync">Got a RemoteException while starting the sync</string>
<string name="status_canceled_sync">Canceled the sync</string>
<string name="status_remote_exception_while_canceling_sync">Got a RemoteException while canceling the sync</string>
<string name="status_received_heartbeat">Received heartbeat</string>
<string name="status_sync_failed_format">Sync failed: %s</string>
<string name="status_sync_succeeded_format">Sync succeeded: %s</string>
<string name="status_already_bound">Already bound to sync adapter</string>
<string name="status_sync_adapter_not_selected">No selected sync adapter</string>
<string name="binding_connected_format">Connected to Sync Adapter\n\tauthority: %s\n\taccount type: %s</string>
<string name="binding_not_connected">Not connected to a sync adapter</string>
<string name="binding_bind_failed">Bind failed</string>
<string name="binding_waiting_for_connection">Waiting for service to be connected...</string>
<string name="select_account_to_sync">Select account to sync</string>
</resources>

View File

@@ -0,0 +1,431 @@
/*
* 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.development;
import android.app.Activity;
import android.app.Dialog;
import android.app.AlertDialog;
import android.content.*;
import android.content.pm.PackageManager;
import android.accounts.*;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Handler;
import android.view.*;
import android.widget.*;
import android.widget.ArrayAdapter;
import android.util.Log;
import android.text.TextUtils;
import java.io.IOException;
public class AccountsTester extends Activity implements OnAccountsUpdateListener {
private static final String TAG = "AccountsTester";
private Spinner mAccountTypesSpinner;
private ListView mAccountsListView;
private ListView mAuthenticatorsListView;
private AccountManager mAccountManager;
private String mLongPressedAccount = null;
private static final String COM_GOOGLE = "com.google";
private AuthenticatorDescription[] mAuthenticatorDescs;
private static final int GET_AUTH_TOKEN_DIALOG_ID = 1;
private static final int UPDATE_CREDENTIALS_DIALOG_ID = 2;
private static final int INVALIDATE_AUTH_TOKEN_DIALOG_ID = 3;
private EditText mDesiredAuthTokenTypeEditText;
private EditText mDesiredFeaturesEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAccountManager = AccountManager.get(this);
setContentView(R.layout.accounts_tester);
ButtonClickListener buttonClickListener = new ButtonClickListener();
mAccountTypesSpinner = (Spinner) findViewById(R.id.accounts_tester_account_types_spinner);
mAccountsListView = (ListView) findViewById(R.id.accounts_tester_accounts_list);
mAuthenticatorsListView = (ListView) findViewById(R.id.accounts_tester_authenticators_list);
registerForContextMenu(mAccountsListView);
getAuthenticatorTypes();
findViewById(R.id.accounts_tester_get_all_accounts).setOnClickListener(buttonClickListener);
findViewById(R.id.accounts_tester_get_accounts_by_type).setOnClickListener(
buttonClickListener);
findViewById(R.id.accounts_tester_add_account).setOnClickListener(buttonClickListener);
findViewById(R.id.accounts_tester_edit_properties).setOnClickListener(buttonClickListener);
mDesiredAuthTokenTypeEditText =
(EditText) findViewById(R.id.accounts_tester_desired_authtokentype);
mDesiredFeaturesEditText = (EditText) findViewById(R.id.accounts_tester_desired_features);
}
private static class AuthenticatorsArrayAdapter extends ArrayAdapter<AuthenticatorDescription> {
protected LayoutInflater mInflater;
private static final int mResource = R.layout.authenticators_list_item;
public AuthenticatorsArrayAdapter(Context context, AuthenticatorDescription[] items) {
super(context, mResource, items);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
static class ViewHolder {
TextView label;
ImageView icon;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.authenticators_list_item, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.label = (TextView) convertView.findViewById(
R.id.accounts_tester_authenticator_label);
holder.icon = (ImageView) convertView.findViewById(
R.id.accounts_tester_authenticator_icon);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
final AuthenticatorDescription desc = getItem(position);
final String packageName = desc.packageName;
try {
final Context authContext = getContext().createPackageContext(packageName, 0);
// Set text field
holder.label.setText(authContext.getString(desc.labelId));
// Set resource icon
holder.icon.setImageDrawable(authContext.getResources().getDrawable(desc.iconId));
} catch (PackageManager.NameNotFoundException e) {
Log.d(TAG, "error getting the Package Context for " + packageName, e);
}
return convertView;
}
}
private void getAuthenticatorTypes() {
mAuthenticatorDescs = mAccountManager.getAuthenticatorTypes();
String[] names = new String[mAuthenticatorDescs.length];
for (int i = 0; i < mAuthenticatorDescs.length; i++) {
Context authContext;
try {
authContext = createPackageContext(mAuthenticatorDescs[i].packageName, 0);
} catch (PackageManager.NameNotFoundException e) {
continue;
}
names[i] = authContext.getString(mAuthenticatorDescs[i].labelId);
}
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(AccountsTester.this,
android.R.layout.simple_spinner_item, names);
mAccountTypesSpinner.setAdapter(adapter);
mAuthenticatorsListView.setAdapter(new AuthenticatorsArrayAdapter(
AccountsTester.this, mAuthenticatorDescs));
}
public void onAccountsUpdated(Account[] accounts) {
Log.d(TAG, "onAccountsUpdated: \n " + TextUtils.join("\n ", accounts));
String[] accountNames = new String[accounts.length];
for (int i = 0; i < accounts.length; i++) {
accountNames[i] = accounts[i].name;
}
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(AccountsTester.this,
android.R.layout.simple_list_item_1, accountNames);
mAccountsListView.setAdapter(adapter);
}
protected void onStart() {
super.onStart();
final Handler mainHandler = new Handler(getMainLooper());
mAccountManager.addOnAccountsUpdatedListener(this, mainHandler,
true /* updateImmediately */);
}
protected void onStop() {
super.onStop();
mAccountManager.removeOnAccountsUpdatedListener(this);
}
class ButtonClickListener implements View.OnClickListener {
public void onClick(View v) {
if (R.id.accounts_tester_get_all_accounts == v.getId()) {
onAccountsUpdated(mAccountManager.getAccounts());
} else if (R.id.accounts_tester_get_accounts_by_type == v.getId()) {
String type = getSelectedAuthenticator().type;
onAccountsUpdated(mAccountManager.getAccountsByType(type));
} else if (R.id.accounts_tester_add_account == v.getId()) {
AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
bundle.keySet();
Log.d(TAG, "account added: " + bundle);
} catch (OperationCanceledException e) {
Log.d(TAG, "addAccount was canceled");
} catch (IOException e) {
Log.d(TAG, "addAccount failed: " + e);
} catch (AuthenticatorException e) {
Log.d(TAG, "addAccount failed: " + e);
}
}
};
String authTokenType = mDesiredAuthTokenTypeEditText.getText().toString();
if (TextUtils.isEmpty(authTokenType)) {
authTokenType = null;
}
String featureString = mDesiredFeaturesEditText.getText().toString();
String[] requiredFeatures = TextUtils.split(featureString, " ");
if (requiredFeatures.length == 0) {
requiredFeatures = null;
}
mAccountManager.addAccount(getSelectedAuthenticator().type,
authTokenType, requiredFeatures, null /* options */,
AccountsTester.this, callback, null /* handler */);
} else if (R.id.accounts_tester_edit_properties == v.getId()) {
mAccountManager.editProperties(getSelectedAuthenticator().type,
AccountsTester.this, new EditPropertiesCallback(), null /* handler */);
} else {
// unknown button
}
}
private class EditPropertiesCallback implements AccountManagerCallback<Bundle> {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
bundle.keySet();
Log.d(TAG, "editProperties succeeded: " + bundle);
} catch (OperationCanceledException e) {
Log.d(TAG, "editProperties was canceled");
} catch (IOException e) {
Log.d(TAG, "editProperties failed: ", e);
} catch (AuthenticatorException e) {
Log.d(TAG, "editProperties failed: ", e);
}
}
}
}
private AuthenticatorDescription getSelectedAuthenticator() {
return mAuthenticatorDescs[mAccountTypesSpinner.getSelectedItemPosition()];
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle(R.string.accounts_tester_account_context_menu_title);
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.account_list_context_menu, menu);
mLongPressedAccount = ((TextView)info.targetView).getText().toString();
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if (item.getItemId() == R.id.accounts_tester_remove_account) {
final Account account = new Account(mLongPressedAccount, COM_GOOGLE);
mAccountManager.removeAccount(account, new AccountManagerCallback<Boolean>() {
public void run(AccountManagerFuture<Boolean> future) {
try {
Log.d(TAG, "removeAccount(" + account + ") = " + future.getResult());
} catch (OperationCanceledException e) {
} catch (IOException e) {
} catch (AuthenticatorException e) {
}
}
}, null /* handler */);
} else if (item.getItemId() == R.id.accounts_tester_get_auth_token) {
showDialog(GET_AUTH_TOKEN_DIALOG_ID);
} else if (item.getItemId() == R.id.accounts_tester_invalidate_auth_token) {
showDialog(INVALIDATE_AUTH_TOKEN_DIALOG_ID);
} else if (item.getItemId() == R.id.accounts_tester_update_credentials) {
showDialog(UPDATE_CREDENTIALS_DIALOG_ID);
} else if (item.getItemId() == R.id.accounts_tester_confirm_credentials) {
mAccountManager.confirmCredentials(new Account(mLongPressedAccount, COM_GOOGLE), null,
AccountsTester.this, new ConfirmCredentialsCallback(), null /* handler */);
}
return true;
}
@Override
protected Dialog onCreateDialog(final int id) {
if (id == GET_AUTH_TOKEN_DIALOG_ID || id == INVALIDATE_AUTH_TOKEN_DIALOG_ID
|| id == UPDATE_CREDENTIALS_DIALOG_ID) {
final View view = LayoutInflater.from(this).inflate(R.layout.get_auth_token_view, null);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setPositiveButton(R.string.accounts_tester_do_get_auth_token,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
EditText value = (EditText) view.findViewById(
R.id.accounts_tester_auth_token_type);
String authTokenType = value.getText().toString();
AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
bundle.keySet();
Log.d(TAG, "dialog " + id + " success: " + bundle);
} catch (OperationCanceledException e) {
Log.d(TAG, "dialog " + id + " canceled");
} catch (IOException e) {
Log.d(TAG, "dialog " + id + " failed: " + e);
} catch (AuthenticatorException e) {
Log.d(TAG, "dialog " + id + " failed: " + e);
}
}
};
final Account account = new Account(mLongPressedAccount,
COM_GOOGLE);
if (id == GET_AUTH_TOKEN_DIALOG_ID) {
mAccountManager.getAuthToken(account, authTokenType,
null /* loginOptions */, AccountsTester.this,
callback, null /* handler */);
} else if (id == INVALIDATE_AUTH_TOKEN_DIALOG_ID) {
mAccountManager.getAuthToken(account, authTokenType, false,
new GetAndInvalidateAuthTokenCallback(), null);
} else {
mAccountManager.updateCredentials(
account,
authTokenType, null /* loginOptions */,
AccountsTester.this, callback, null /* handler */);
}
}
});
builder.setView(view);
return builder.create();
}
return super.onCreateDialog(id);
}
AccountManagerCallback<Bundle> newAccountsCallback(String type, String[] features) {
return new GetAccountsCallback(type, features);
}
class GetAccountsCallback implements AccountManagerCallback<Bundle> {
final String[] mFeatures;
final String mAccountType;
public GetAccountsCallback(String type, String[] features) {
mFeatures = features;
mAccountType = type;
}
public void run(AccountManagerFuture<Bundle> future) {
Log.d(TAG, "GetAccountsCallback: type " + mAccountType
+ ", features "
+ (mFeatures == null ? "none" : TextUtils.join(",", mFeatures)));
try {
Bundle result = future.getResult();
Parcelable[] accounts = result.getParcelableArray(AccountManager.KEY_ACCOUNTS);
Log.d(TAG, "found " + accounts.length + " accounts");
for (Parcelable account : accounts) {
Log.d(TAG, " " + account);
}
} catch (OperationCanceledException e) {
Log.d(TAG, "failure", e);
} catch (IOException e) {
Log.d(TAG, "failure", e);
} catch (AuthenticatorException e) {
Log.d(TAG, "failure", e);
}
}
}
AccountManagerCallback<Bundle> newAuthTokensCallback(String type, String authTokenType, String[] features) {
return new GetAuthTokenCallback(type, authTokenType, features);
}
class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
final String[] mFeatures;
final String mAccountType;
final String mAuthTokenType;
public GetAuthTokenCallback(String type, String authTokenType, String[] features) {
mFeatures = features;
mAccountType = type;
mAuthTokenType = authTokenType;
}
public void run(AccountManagerFuture<Bundle> future) {
Log.d(TAG, "GetAuthTokenCallback: type " + mAccountType
+ ", features "
+ (mFeatures == null ? "none" : TextUtils.join(",", mFeatures)));
try {
Bundle result = future.getResult();
result.keySet();
Log.d(TAG, " result: " + result);
} catch (OperationCanceledException e) {
Log.d(TAG, "failure", e);
} catch (IOException e) {
Log.d(TAG, "failure", e);
} catch (AuthenticatorException e) {
Log.d(TAG, "failure", e);
}
}
}
private class GetAndInvalidateAuthTokenCallback implements AccountManagerCallback<Bundle> {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
mAccountManager.invalidateAuthToken(COM_GOOGLE, authToken);
} catch (OperationCanceledException e) {
Log.d(TAG, "invalidate: interrupted while getting authToken");
} catch (IOException e) {
Log.d(TAG, "invalidate: error getting authToken", e);
} catch (AuthenticatorException e) {
Log.d(TAG, "invalidate: error getting authToken", e);
}
}
}
private static class ConfirmCredentialsCallback implements AccountManagerCallback<Bundle> {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
bundle.keySet();
Log.d(TAG, "confirmCredentials success: " + bundle);
} catch (OperationCanceledException e) {
Log.d(TAG, "confirmCredentials canceled");
} catch (AuthenticatorException e) {
Log.d(TAG, "confirmCredentials failed: " + e);
} catch (IOException e) {
Log.d(TAG, "confirmCredentials failed: " + e);
}
}
}
}

View File

@@ -17,11 +17,14 @@
package com.android.development;
import com.android.development.PackageBrowser.MyPackageInfo;
import android.app.ActivityManagerNative;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.Settings;
@@ -29,10 +32,12 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -67,96 +72,67 @@ public class AppPicker extends ListActivity
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
{
ApplicationInfo app = mAdapter.appForPosition(position);
MyApplicationInfo app = mAdapter.itemForPosition(position);
Intent intent = new Intent();
if (app != null) intent.setAction(app.packageName);
if (app.info != null) intent.setAction(app.info.packageName);
setResult(RESULT_OK, intent);
/* This is a temporary fix for 824637 while it is blocked by 805226. When 805226 is resolved, please remove this. */
try {
boolean waitForDebugger = Settings.System.getInt(
getContentResolver(), Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
ActivityManagerNative.getDefault().setDebugApp(
app != null ? app.packageName : null, waitForDebugger, true);
app.info != null ? app.info.packageName : null, waitForDebugger, true);
} catch (RemoteException ex) {
}
finish();
}
private final class AppListAdapter extends BaseAdapter
{
public AppListAdapter(Context context)
{
mContext = context;
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
class MyApplicationInfo {
ApplicationInfo info;
String label;
}
public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
private List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
mList = context.getPackageManager().getInstalledApplications(0);
if (mList != null) {
Collections.sort(mList, sDisplayNameComparator);
mList.add(0, null);
public AppListAdapter(Context context) {
super(context, R.layout.package_list_item);
List<ApplicationInfo> pkgs = context.getPackageManager().getInstalledApplications(0);
for (int i=0; i<pkgs.size(); i++) {
MyApplicationInfo info = new MyApplicationInfo();
info.info = pkgs.get(i);
info.label = info.info.loadLabel(getPackageManager()).toString();
mPackageInfoList.add(info);
}
Collections.sort(mPackageInfoList, sDisplayNameComparator);
MyApplicationInfo info = new MyApplicationInfo();
info.label = "(none)";
mPackageInfoList.add(0, info);
setSource(mPackageInfoList);
}
public ApplicationInfo appForPosition(int position)
{
if (mList == null) {
return null;
}
return mList.get(position);
}
public int getCount()
{
return mList != null ? mList.size() : 0;
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View view;
if (convertView == null) {
view = mInflater.inflate(
android.R.layout.simple_list_item_1, parent, false);
@Override
public void bindView(View view, MyApplicationInfo info) {
ImageView icon = (ImageView)view.findViewById(R.id.icon);
TextView name = (TextView)view.findViewById(R.id.name);
TextView description = (TextView)view.findViewById(R.id.description);
name.setText(info.label);
if (info.info != null) {
icon.setImageDrawable(info.info.loadIcon(getPackageManager()));
description.setText(info.info.packageName);
} else {
view = convertView;
icon.setImageDrawable(null);
description.setText("");
}
bindView(view, mList.get(position));
return view;
}
private final void bindView(View view, ApplicationInfo info)
{
TextView text = (TextView)view.findViewById(android.R.id.text1);
text.setText(info != null ? info.packageName : "(none)");
}
protected final Context mContext;
protected final LayoutInflater mInflater;
protected List<ApplicationInfo> mList;
}
private final static Comparator sDisplayNameComparator = new Comparator() {
private final static Comparator<MyApplicationInfo> sDisplayNameComparator
= new Comparator<MyApplicationInfo>() {
public final int
compare(Object a, Object b)
{
CharSequence sa = ((ApplicationInfo) a).packageName;
CharSequence sb = ((ApplicationInfo) b).packageName;
return collator.compare(sa, sb);
compare(MyApplicationInfo a, MyApplicationInfo b) {
return collator.compare(a.label, b.label);
}
private final Collator collator = Collator.getInstance();

View File

@@ -38,6 +38,7 @@ import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
import java.io.FileInputStream;
@@ -58,6 +59,7 @@ public class DevelopmentSettings extends Activity {
private CheckBox mShowBackgroundCB;
private CheckBox mShowSleepCB;
private CheckBox mShowXmppCB;
private CheckBox mCompatibilityModeCB;
private Spinner mMaxProcsSpinner;
private Spinner mWindowAnimationScaleSpinner;
private Spinner mTransitionAnimationScaleSpinner;
@@ -69,6 +71,7 @@ public class DevelopmentSettings extends Activity {
private int mProcessLimit;
private boolean mShowSleep;
private boolean mShowXmpp;
private boolean mCompatibilityMode;
private AnimationScaleSelectedListener mWindowAnimationScale
= new AnimationScaleSelectedListener(0);
private AnimationScaleSelectedListener mTransitionAnimationScale
@@ -106,6 +109,8 @@ public class DevelopmentSettings extends Activity {
mShowSleepCB.setOnClickListener(mShowSleepClicked);
mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
mShowXmppCB.setOnClickListener(mShowXmppClicked);
mCompatibilityModeCB = (CheckBox)findViewById(R.id.compatibility_mode);
mCompatibilityModeCB.setOnClickListener(mCompatibilityModeClicked);
mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
mMaxProcsSpinner.setOnItemSelectedListener(mMaxProcsChanged);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
@@ -168,7 +173,8 @@ public class DevelopmentSettings extends Activity {
updateSharedOptions();
updateFlingerOptions();
updateSleepOptions();
updateXmppOptions();
updateXmppOptions();
updateCompatibilityOptions();
try {
FileInputStream in = new FileInputStream( FONT_HINTING_FILE );
@@ -235,6 +241,17 @@ public class DevelopmentSettings extends Activity {
Settings.System.SHOW_PROCESSES, 0) != 0);
}
private void writeCompatibilityOptions() {
Settings.System.putInt(getContentResolver(),
Settings.System.COMPATIBILITY_MODE, mCompatibilityMode ? 0 : 1);
}
private void updateCompatibilityOptions() {
mCompatibilityMode = Settings.System.getInt(
getContentResolver(), Settings.System.COMPATIBILITY_MODE, 1) == 0;
mCompatibilityModeCB.setChecked(mCompatibilityMode);
}
private void updateFlingerOptions() {
// magic communication with surface flinger.
try {
@@ -332,6 +349,19 @@ public class DevelopmentSettings extends Activity {
}
};
private View.OnClickListener mCompatibilityModeClicked =
new View.OnClickListener() {
public void onClick(View v) {
mCompatibilityMode = ((CheckBox)v).isChecked();
writeCompatibilityOptions();
updateCompatibilityOptions();
Toast toast = Toast.makeText(DevelopmentSettings.this,
R.string.development_settings_compatibility_mode_toast,
Toast.LENGTH_LONG);
toast.show();
}
};
private View.OnClickListener mShowLoadClicked = new View.OnClickListener() {
public void onClick(View v) {
boolean value = ((CheckBox)v).isChecked();

View File

@@ -31,27 +31,38 @@ import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class PackageBrowser extends ListActivity
{
public class PackageBrowser extends ListActivity {
static class MyPackageInfo {
PackageInfo info;
String label;
}
private PackageListAdapter mAdapter;
private List<PackageInfo> mPackageInfoList = null;
private List<MyPackageInfo> mPackageInfoList = new ArrayList<MyPackageInfo>();
private Handler mHandler;
private BroadcastReceiver mRegisteredReceiver;
public class PackageListAdapter extends ArrayAdapter<PackageInfo>
{
public class PackageListAdapter extends ArrayAdapter<MyPackageInfo> {
public PackageListAdapter(Context context)
{
super(context, android.R.layout.simple_list_item_1);
mPackageInfoList = context.getPackageManager().getInstalledPackages(0);
public PackageListAdapter(Context context) {
super(context, R.layout.package_list_item);
List<PackageInfo> pkgs = context.getPackageManager().getInstalledPackages(0);
for (int i=0; i<pkgs.size(); i++) {
MyPackageInfo info = new MyPackageInfo();
info.info = pkgs.get(i);
info.label = info.info.applicationInfo.loadLabel(getPackageManager()).toString();
mPackageInfoList.add(info);
}
if (mPackageInfoList != null) {
Collections.sort(mPackageInfoList, sDisplayNameComparator);
}
@@ -59,10 +70,13 @@ public class PackageBrowser extends ListActivity
}
@Override
public void bindView(View view, PackageInfo info)
{
TextView text = (TextView)view.findViewById(android.R.id.text1);
text.setText(info.packageName);
public void bindView(View view, MyPackageInfo info) {
ImageView icon = (ImageView)view.findViewById(R.id.icon);
TextView name = (TextView)view.findViewById(R.id.name);
TextView description = (TextView)view.findViewById(R.id.description);
icon.setImageDrawable(info.info.applicationInfo.loadIcon(getPackageManager()));
name.setText(info.label);
description.setText(info.info.packageName);
}
}
@@ -78,13 +92,11 @@ public class PackageBrowser extends ListActivity
}
}
private final static Comparator sDisplayNameComparator = new Comparator() {
private final static Comparator<MyPackageInfo> sDisplayNameComparator
= new Comparator<MyPackageInfo>() {
public final int
compare(Object a, Object b)
{
CharSequence sa = ((PackageInfo) a).packageName;
CharSequence sb = ((PackageInfo) b).packageName;
return collator.compare(sa, sb);
compare(MyPackageInfo a, MyPackageInfo b) {
return collator.compare(a.label, b.label);
}
private final Collator collator = Collator.getInstance();
@@ -98,6 +110,14 @@ public class PackageBrowser extends ListActivity
registerIntentReceivers();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mRegisteredReceiver != null) {
unregisterReceiver(mRegisteredReceiver);
}
}
private void setupAdapter() {
mAdapter = new PackageListAdapter(this);
setListAdapter(mAdapter);
@@ -119,9 +139,9 @@ public class PackageBrowser extends ListActivity
final int curSelection = getSelectedItemPosition();
if (curSelection >= 0) {
// todo: verification dialog for package deletion
final PackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
final MyPackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
if (packageInfo != null) {
getPackageManager().deletePackage(packageInfo.packageName,
getPackageManager().deletePackage(packageInfo.info.packageName,
new IPackageDeleteObserver.Stub() {
public void packageDeleted(boolean succeeded) throws RemoteException {
if (succeeded) {
@@ -133,7 +153,7 @@ public class PackageBrowser extends ListActivity
});
// todo: verification dialog for data directory
final String dataPath = packageInfo.applicationInfo.dataDir;
final String dataPath = packageInfo.info.applicationInfo.dataDir;
// todo: delete the data directory
} else {
mHandler.post(new Runnable() {
@@ -159,17 +179,17 @@ public class PackageBrowser extends ListActivity
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
registerReceiver(new ApplicationsIntentReceiver(), filter);
mRegisteredReceiver = new ApplicationsIntentReceiver();
registerReceiver(mRegisteredReceiver, filter);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
{
PackageInfo info =
protected void onListItemClick(ListView l, View v, int position, long id) {
MyPackageInfo info =
mAdapter.itemForPosition(position);
if (info != null) {
Intent intent = new Intent(
null, Uri.fromParts("package", info.packageName, null));
null, Uri.fromParts("package", info.info.packageName, null));
intent.setClass(this, PackageSummary.class);
startActivity(intent);
}

View File

@@ -31,6 +31,7 @@ import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
@@ -90,7 +91,8 @@ public class PackageSummary extends Activity {
info = pm.getPackageInfo(mPackageName,
PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
| PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS
| PackageManager.GET_INSTRUMENTATION);
| PackageManager.GET_INSTRUMENTATION
| PackageManager.GET_DISABLED_COMPONENTS);
} catch (PackageManager.NameNotFoundException e) {
}
@@ -192,6 +194,7 @@ public class PackageSummary extends Activity {
ActivityInfo ai = info.receivers[i];
Button view = (Button)inflate.inflate(
R.layout.package_item, null, false);
Log.i("foo", "Receiver #" + i + " of " + N + ": " + ai);
setItemText(view, info, ai.name);
receivers.addView(view, lp);
}

View File

@@ -20,11 +20,11 @@ import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.FontMetricsInt;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.VelocityTracker;
import android.view.View;
@@ -47,16 +47,9 @@ public class PointerLocation extends Activity {
getWindow().setAttributes(lp);
}
public class MyView extends View {
private final Paint mTextPaint;
private final Paint mTextBackgroundPaint;
private final Paint mTextLevelPaint;
private final Paint mPaint;
private final Paint mTargetPaint;
private final FontMetricsInt mTextMetrics = new FontMetricsInt();
public static class PointerState {
private final ArrayList<Float> mXs = new ArrayList<Float>();
private final ArrayList<Float> mYs = new ArrayList<Float>();
private int mHeaderBottom;
private boolean mCurDown;
private int mCurX;
private int mCurY;
@@ -64,12 +57,31 @@ public class PointerLocation extends Activity {
private float mCurSize;
private int mCurWidth;
private VelocityTracker mVelocity;
}
public class MyView extends View {
private final ViewConfiguration mVC;
private final Paint mTextPaint;
private final Paint mTextBackgroundPaint;
private final Paint mTextLevelPaint;
private final Paint mPaint;
private final Paint mTargetPaint;
private final Paint mPathPaint;
private final FontMetricsInt mTextMetrics = new FontMetricsInt();
private int mHeaderBottom;
private boolean mCurDown;
private int mCurNumPointers;
private int mMaxNumPointers;
private final ArrayList<PointerState> mPointers
= new ArrayList<PointerState>();
public MyView(Context c) {
super(c);
mVC = ViewConfiguration.get(c);
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(10);
mTextPaint.setTextSize(10
* getResources().getDisplayMetrics().density);
mTextPaint.setARGB(255, 0, 0, 0);
mTextBackgroundPaint = new Paint();
mTextBackgroundPaint.setAntiAlias(false);
@@ -84,9 +96,16 @@ public class PointerLocation extends Activity {
mPaint.setStrokeWidth(2);
mTargetPaint = new Paint();
mTargetPaint.setAntiAlias(false);
mTargetPaint.setARGB(192, 0, 0, 255);
mTargetPaint.setARGB(255, 0, 0, 192);
mPathPaint = new Paint();
mPathPaint.setAntiAlias(false);
mPathPaint.setARGB(255, 0, 96, 255);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(1);
PointerState ps = new PointerState();
ps.mVelocity = VelocityTracker.obtain();
mPointers.add(ps);
}
@Override
@@ -103,58 +122,119 @@ public class PointerLocation extends Activity {
@Override
protected void onDraw(Canvas canvas) {
int w = getWidth()/5;
int base = -mTextMetrics.ascent+1;
int bottom = mHeaderBottom;
canvas.drawRect(0, 0, w-1, bottom, mTextBackgroundPaint);
canvas.drawText("X: " + mCurX, 1, base, mTextPaint);
canvas.drawRect(w, 0, (w * 2) - 1, bottom, mTextBackgroundPaint);
canvas.drawText("Y: " + mCurY, 1 + w, base, mTextPaint);
canvas.drawRect(w * 2, 0, (w * 3) - 1, bottom, mTextBackgroundPaint);
canvas.drawRect(w * 2, 0, (w * 2) + (mCurPressure * w) - 1, bottom, mTextLevelPaint);
canvas.drawText("Pres: " + mCurPressure, 1 + w * 2, base, mTextPaint);
canvas.drawRect(w * 3, 0, (w * 4) - 1, bottom, mTextBackgroundPaint);
canvas.drawRect(w * 3, 0, (w * 3) + (mCurSize * w) - 1, bottom, mTextLevelPaint);
canvas.drawText("Size: " + mCurSize, 1 + w * 3, base, mTextPaint);
canvas.drawRect(w * 4, 0, getWidth(), bottom, mTextBackgroundPaint);
int velocity = mVelocity == null ? 0 : (int) (mVelocity.getYVelocity() * 1000);
canvas.drawText("yVel: " + velocity, 1 + w * 4, base, mTextPaint);
final int w = getWidth();
final int itemW = w/7;
final int base = -mTextMetrics.ascent+1;
final int bottom = mHeaderBottom;
final int N = mXs.size();
float lastX=0, lastY=0;
mPaint.setARGB(255, 0, 255, 255);
for (int i=0; i<N; i++) {
float x = mXs.get(i);
float y = mYs.get(i);
if (i > 0) {
canvas.drawLine(lastX, lastY, x, y, mTargetPaint);
canvas.drawPoint(lastX, lastY, mPaint);
final int NP = mPointers.size();
if (NP > 0) {
final PointerState ps = mPointers.get(0);
canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
1, base, mTextPaint);
final int N = ps.mXs.size();
if ((mCurDown && ps.mCurDown) || N == 0) {
canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
} else {
float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
Math.abs(dx) < mVC.getScaledTouchSlop()
? mTextBackgroundPaint : mTextLevelPaint);
canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);
canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,
Math.abs(dy) < mVC.getScaledTouchSlop()
? mTextBackgroundPaint : mTextLevelPaint);
canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);
}
lastX = x;
lastY = y;
}
if (mVelocity != null) {
mPaint.setARGB(255, 255, 0, 0);
float xVel = mVelocity.getXVelocity() * (1000/60);
float yVel = mVelocity.getYVelocity() * (1000/60);
canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
} else {
canvas.drawPoint(lastX, lastY, mPaint);
canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
int velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getXVelocity() * 1000);
canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getYVelocity() * 1000);
canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
bottom, mTextLevelPaint);
canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
base, mTextPaint);
canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
bottom, mTextLevelPaint);
canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
base, mTextPaint);
}
if (mCurDown) {
canvas.drawLine(0, (int)mCurY, getWidth(), (int)mCurY, mTargetPaint);
canvas.drawLine((int)mCurX, 0, (int)mCurX, getHeight(), mTargetPaint);
int pressureLevel = (int)(mCurPressure*255);
mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
canvas.drawPoint(mCurX, mCurY, mPaint);
canvas.drawCircle(mCurX, mCurY, mCurWidth, mPaint);
for (int p=0; p<NP; p++) {
final PointerState ps = mPointers.get(p);
if (mCurDown && ps.mCurDown) {
canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
int pressureLevel = (int)(ps.mCurPressure*255);
mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
}
}
for (int p=0; p<NP; p++) {
final PointerState ps = mPointers.get(p);
final int N = ps.mXs.size();
float lastX=0, lastY=0;
boolean haveLast = false;
boolean drawn = false;
mPaint.setARGB(255, 128, 255, 255);
for (int i=0; i<N; i++) {
float x = ps.mXs.get(i);
float y = ps.mYs.get(i);
if (Float.isNaN(x)) {
haveLast = false;
continue;
}
if (haveLast) {
canvas.drawLine(lastX, lastY, x, y, mPathPaint);
canvas.drawPoint(lastX, lastY, mPaint);
drawn = true;
}
lastX = x;
lastY = y;
haveLast = true;
}
if (drawn) {
if (ps.mVelocity != null) {
mPaint.setARGB(255, 255, 64, 128);
float xVel = ps.mVelocity.getXVelocity() * (1000/60);
float yVel = ps.mVelocity.getYVelocity() * (1000/60);
canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
} else {
canvas.drawPoint(lastX, lastY, mPaint);
}
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
//Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
// + " pointers=" + event.getPointerCount());
int NP = mPointers.size();
//mRect.set(0, 0, getWidth(), mHeaderBottom+1);
//invalidate(mRect);
//if (mCurDown) {
@@ -164,26 +244,91 @@ public class PointerLocation extends Activity {
// mRect.setEmpty();
//}
if (action == MotionEvent.ACTION_DOWN) {
mXs.clear();
mYs.clear();
mVelocity = VelocityTracker.obtain();
for (int p=0; p<NP; p++) {
final PointerState ps = mPointers.get(p);
ps.mXs.clear();
ps.mYs.clear();
ps.mVelocity = VelocityTracker.obtain();
ps.mCurDown = false;
}
mPointers.get(0).mCurDown = true;
mMaxNumPointers = 0;
Log.i("Pointer", "Pointer 1: DOWN");
}
mVelocity.addMovement(event);
mVelocity.computeCurrentVelocity(1);
final int N = event.getHistorySize();
for (int i=0; i<N; i++) {
mXs.add(event.getHistoricalX(i));
mYs.add(event.getHistoricalY(i));
if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
>> MotionEvent.ACTION_POINTER_ID_SHIFT;
while (NP <= id) {
PointerState ps = new PointerState();
ps.mVelocity = VelocityTracker.obtain();
mPointers.add(ps);
NP++;
}
final PointerState ps = mPointers.get(id);
ps.mVelocity = VelocityTracker.obtain();
ps.mCurDown = true;
Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");
}
mXs.add(event.getX());
mYs.add(event.getY());
mCurDown = action == MotionEvent.ACTION_DOWN
|| action == MotionEvent.ACTION_MOVE;
mCurX = (int)event.getX();
mCurY = (int)event.getY();
mCurPressure = event.getPressure();
mCurSize = event.getSize();
mCurWidth = (int)(mCurSize*(getWidth()/3));
final int NI = event.getPointerCount();
mCurDown = action != MotionEvent.ACTION_UP
&& action != MotionEvent.ACTION_CANCEL;
mCurNumPointers = mCurDown ? NI : 0;
if (mMaxNumPointers < mCurNumPointers) {
mMaxNumPointers = mCurNumPointers;
}
for (int i=0; i<NI; i++) {
final PointerState ps = mPointers.get(event.getPointerId(i));
ps.mVelocity.addMovement(event);
ps.mVelocity.computeCurrentVelocity(1);
final int N = event.getHistorySize();
for (int j=0; j<N; j++) {
Log.i("Pointer", "Pointer " + (i+1) + ": ("
+ event.getHistoricalX(i, j)
+ ", " + event.getHistoricalY(i, j) + ")"
+ " Prs=" + event.getHistoricalPressure(i, j)
+ " Size=" + event.getHistoricalSize(i, j));
ps.mXs.add(event.getHistoricalX(i, j));
ps.mYs.add(event.getHistoricalY(i, j));
}
Log.i("Pointer", "Pointer " + (i+1) + ": ("
+ event.getX(i) + ", " + event.getY(i) + ")"
+ " Prs=" + event.getPressure(i)
+ " Size=" + event.getSize(i));
ps.mXs.add(event.getX(i));
ps.mYs.add(event.getY(i));
ps.mCurX = (int)event.getX(i);
ps.mCurY = (int)event.getY(i);
//Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
// + "," + ps.mCurY + ")");
ps.mCurPressure = event.getPressure(i);
ps.mCurSize = event.getSize(i);
ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
}
if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
>> MotionEvent.ACTION_POINTER_ID_SHIFT;
final PointerState ps = mPointers.get(id);
ps.mXs.add(Float.NaN);
ps.mYs.add(Float.NaN);
ps.mCurDown = false;
Log.i("Pointer", "Pointer " + (id+1) + ": UP");
}
if (action == MotionEvent.ACTION_UP) {
for (int i=0; i<NI; i++) {
final PointerState ps = mPointers.get(event.getPointerId(i));
if (ps.mCurDown) {
ps.mCurDown = false;
Log.i("Pointer", "Pointer " + (i+1) + ": UP");
}
}
}
//if (mCurDown) {
// mRect.union(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
// mCurX+mCurWidth+3, mCurY+mCurWidth+3);

View File

@@ -0,0 +1,374 @@
/*
* 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.development;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.Dialog;
import android.app.AlertDialog;
import android.content.res.TypedArray;
import android.content.pm.RegisteredServicesCache;
import android.content.pm.RegisteredServicesCacheListener;
import android.content.SyncAdapterType;
import android.content.ISyncAdapter;
import android.content.ISyncContext;
import android.content.ServiceConnection;
import android.content.ComponentName;
import android.content.SyncResult;
import android.content.Intent;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ListView;
import android.util.AttributeSet;
import android.provider.Settings;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.view.View;
import android.view.LayoutInflater;
import java.util.Collection;
public class SyncAdapterDriver extends Activity
implements RegisteredServicesCacheListener<SyncAdapterType>,
AdapterView.OnItemClickListener {
private Spinner mSyncAdapterSpinner;
private Button mBindButton;
private Button mUnbindButton;
private TextView mBoundAdapterTextView;
private Button mStartSyncButton;
private Button mCancelSyncButton;
private TextView mStatusTextView;
private Object[] mSyncAdapters;
private SyncAdaptersCache mSyncAdaptersCache;
private final Object mSyncAdaptersLock = new Object();
private static final int DIALOG_ID_PICK_ACCOUNT = 1;
private ListView mAccountPickerView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSyncAdaptersCache = new SyncAdaptersCache(this);
setContentView(R.layout.sync_adapter_driver);
mSyncAdapterSpinner = (Spinner) findViewById(R.id.sync_adapters_spinner);
mBindButton = (Button) findViewById(R.id.bind_button);
mUnbindButton = (Button) findViewById(R.id.unbind_button);
mBoundAdapterTextView = (TextView) findViewById(R.id.bound_adapter_text_view);
mStartSyncButton = (Button) findViewById(R.id.start_sync_button);
mCancelSyncButton = (Button) findViewById(R.id.cancel_sync_button);
mStatusTextView = (TextView) findViewById(R.id.status_text_view);
getSyncAdapters();
mSyncAdaptersCache.setListener(this, null /* Handler */);
}
protected void onDestroy() {
mSyncAdaptersCache.close();
super.onDestroy();
}
private void getSyncAdapters() {
Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> all =
mSyncAdaptersCache.getAllServices();
synchronized (mSyncAdaptersLock) {
mSyncAdapters = new Object[all.size()];
String[] names = new String[mSyncAdapters.length];
int i = 0;
for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> item : all) {
mSyncAdapters[i] = item;
names[i] = item.type.authority + " - " + item.type.accountType;
i++;
}
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this,
R.layout.sync_adapter_item, names);
mSyncAdapterSpinner.setAdapter(adapter);
}
}
void updateUi() {
boolean isBound;
boolean hasServiceConnection;
synchronized (mServiceConnectionLock) {
hasServiceConnection = mActiveServiceConnection != null;
isBound = hasServiceConnection && mActiveServiceConnection.mBoundSyncAdapter != null;
}
mStartSyncButton.setEnabled(isBound);
mCancelSyncButton.setEnabled(isBound);
mBindButton.setEnabled(!hasServiceConnection);
mUnbindButton.setEnabled(hasServiceConnection);
}
public void startSyncSelected(View view) {
synchronized (mServiceConnectionLock) {
ISyncAdapter syncAdapter = null;
if (mActiveServiceConnection != null) {
syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
}
if (syncAdapter != null) {
removeDialog(DIALOG_ID_PICK_ACCOUNT);
mAccountPickerView = (ListView) LayoutInflater.from(this).inflate(
R.layout.account_list_view, null);
mAccountPickerView.setOnItemClickListener(this);
Account accounts[] = AccountManager.get(this).getAccountsByType(
mActiveServiceConnection.mSyncAdapter.type.accountType);
String[] accountNames = new String[accounts.length];
for (int i = 0; i < accounts.length; i++) {
accountNames[i] = accounts[i].name;
}
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(SyncAdapterDriver.this,
android.R.layout.simple_list_item_1, accountNames);
mAccountPickerView.setAdapter(adapter);
showDialog(DIALOG_ID_PICK_ACCOUNT);
}
}
updateUi();
}
private void startSync(String accountName) {
synchronized (mServiceConnectionLock) {
ISyncAdapter syncAdapter = null;
if (mActiveServiceConnection != null) {
syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
}
if (syncAdapter != null) {
try {
mStatusTextView.setText(
getString(R.string.status_starting_sync_format, accountName));
Account account = new Account(accountName,
mActiveServiceConnection.mSyncAdapter.type.accountType);
syncAdapter.startSync(mActiveServiceConnection,
mActiveServiceConnection.mSyncAdapter.type.authority,
account, new Bundle());
} catch (RemoteException e) {
mStatusTextView.setText(
getString(R.string.status_remote_exception_while_starting_sync));
}
}
}
updateUi();
}
public void cancelSync(View view) {
synchronized (mServiceConnectionLock) {
ISyncAdapter syncAdapter = null;
if (mActiveServiceConnection != null) {
syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
}
if (syncAdapter != null) {
try {
mStatusTextView.setText(getString(R.string.status_canceled_sync));
syncAdapter.cancelSync(mActiveServiceConnection);
} catch (RemoteException e) {
mStatusTextView.setText(
getString(R.string.status_remote_exception_while_canceling_sync));
}
}
}
updateUi();
}
public void onServiceChanged(SyncAdapterType type, boolean removed) {
getSyncAdapters();
}
@Override
protected Dialog onCreateDialog(final int id) {
if (id == DIALOG_ID_PICK_ACCOUNT) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.select_account_to_sync);
builder.setInverseBackgroundForced(true);
builder.setView(mAccountPickerView);
return builder.create();
}
return super.onCreateDialog(id);
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView item = (TextView) view;
final String accountName = item.getText().toString();
dismissDialog(DIALOG_ID_PICK_ACCOUNT);
startSync(accountName);
}
private class MyServiceConnection extends ISyncContext.Stub implements ServiceConnection {
private volatile ISyncAdapter mBoundSyncAdapter;
final RegisteredServicesCache.ServiceInfo<SyncAdapterType> mSyncAdapter;
public MyServiceConnection(
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter) {
mSyncAdapter = syncAdapter;
}
public void onServiceConnected(ComponentName name, IBinder service) {
mBoundSyncAdapter = ISyncAdapter.Stub.asInterface(service);
final SyncAdapterType type = mActiveServiceConnection.mSyncAdapter.type;
mBoundAdapterTextView.setText(getString(R.string.binding_connected_format,
type.authority, type.accountType));
updateUi();
}
public void onServiceDisconnected(ComponentName name) {
mBoundAdapterTextView.setText(getString(R.string.binding_not_connected));
mBoundSyncAdapter = null;
updateUi();
}
public void sendHeartbeat() {
runOnUiThread(new Runnable() {
public void run() {
uiThreadSendHeartbeat();
}
});
}
public void uiThreadSendHeartbeat() {
mStatusTextView.setText(getString(R.string.status_received_heartbeat));
}
public void uiThreadOnFinished(SyncResult result) {
if (result.hasError()) {
mStatusTextView.setText(
getString(R.string.status_sync_failed_format, result.toString()));
} else {
mStatusTextView.setText(
getString(R.string.status_sync_succeeded_format, result.toString()));
}
}
public void onFinished(final SyncResult result) throws RemoteException {
runOnUiThread(new Runnable() {
public void run() {
uiThreadOnFinished(result);
}
});
}
}
final Object mServiceConnectionLock = new Object();
MyServiceConnection mActiveServiceConnection;
public void initiateBind(View view) {
synchronized (mServiceConnectionLock) {
if (mActiveServiceConnection != null) {
mStatusTextView.setText(getString(R.string.status_already_bound));
return;
}
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter =
getSelectedSyncAdapter();
if (syncAdapter == null) {
mStatusTextView.setText(getString(R.string.status_sync_adapter_not_selected));
return;
}
mActiveServiceConnection = new MyServiceConnection(syncAdapter);
Intent intent = new Intent();
intent.setAction("android.content.SyncAdapter");
intent.setComponent(syncAdapter.componentName);
intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
com.android.internal.R.string.sync_binding_label);
intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
this, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0));
if (!bindService(intent, mActiveServiceConnection, Context.BIND_AUTO_CREATE)) {
mBoundAdapterTextView.setText(getString(R.string.binding_bind_failed));
mActiveServiceConnection = null;
return;
}
mBoundAdapterTextView.setText(getString(R.string.binding_waiting_for_connection));
}
updateUi();
}
public void initiateUnbind(View view) {
synchronized (mServiceConnectionLock) {
if (mActiveServiceConnection == null) {
return;
}
mBoundAdapterTextView.setText("");
unbindService(mActiveServiceConnection);
mActiveServiceConnection = null;
}
updateUi();
}
private RegisteredServicesCache.ServiceInfo<SyncAdapterType> getSelectedSyncAdapter() {
synchronized (mSyncAdaptersLock) {
final int position = mSyncAdapterSpinner.getSelectedItemPosition();
if (position == AdapterView.INVALID_POSITION) {
return null;
}
try {
//noinspection unchecked
return (RegisteredServicesCache.ServiceInfo<SyncAdapterType>)
mSyncAdapters[position];
} catch (Exception e) {
return null;
}
}
}
static class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> {
private static final String SERVICE_INTERFACE = "android.content.SyncAdapter";
private static final String SERVICE_META_DATA = "android.content.SyncAdapter";
private static final String ATTRIBUTES_NAME = "sync-adapter";
SyncAdaptersCache(Context context) {
super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, null);
}
public SyncAdapterType parseServiceAttributes(String packageName, AttributeSet attrs) {
TypedArray sa = mContext.getResources().obtainAttributes(attrs,
com.android.internal.R.styleable.SyncAdapter);
try {
final String authority =
sa.getString(com.android.internal.R.styleable.SyncAdapter_contentAuthority);
final String accountType =
sa.getString(com.android.internal.R.styleable.SyncAdapter_accountType);
if (authority == null || accountType == null) {
return null;
}
final boolean userVisible = sa.getBoolean(
com.android.internal.R.styleable.SyncAdapter_userVisible, true);
final boolean supportsUploading = sa.getBoolean(
com.android.internal.R.styleable.SyncAdapter_supportsUploading, true);
return new SyncAdapterType(authority, accountType, userVisible, supportsUploading);
} finally {
sa.recycle();
}
}
}
}

View File

@@ -30,8 +30,7 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
class FontLab extends Activity
{
public class FontLab extends Activity {
private static final int MIN_SIZE = 1;
private static final int MAX_SIZE = 60;
@@ -39,6 +38,10 @@ class FontLab extends Activity
private static final int MAX_SCALE_X = 20;
private static final int MIN_SCALE_X = -19; // -20 would make zero-scale
private static final int MAX_GAMMA = 40;
private static final int MIN_GAMMA = 1;
private static final float GAMMA_RANGE = 20;
private static final String[] sText = {
"Applications Contacts Maps Google Browser Text messages Address book"
+ " Development Earth Quake Settings Voicemail Zoolander. Four score"
@@ -107,13 +110,17 @@ class FontLab extends Activity
updateText();
setDefaultKeyMode(Activity.DEFAULT_KEYS_SHORTCUT);
mColumn1.setPadding(5, 0, 5, 0);
mColumn2.setPadding(5, 0, 5, 0);
}
private void updateTitle() {
Typeface tf = mColumn1.getTypeface();
String title = " ps=" + mFontSize + " scaleX="
String title = " PS=" + mFontSize + " X="
+ (1 + mTextScaleXDelta/SCALE_X_RANGE)
+ " gamma=" + (mGamma/20.f)
+ " G=" + (mGamma/GAMMA_RANGE)
+ " S=" + ((mColumn1.getPaintFlags() & Paint.SUBPIXEL_TEXT_FLAG) != 0 ? 1 : 0)
+ " " + sTypefaceName[mFontIndex]
+ " " + sStyleName[tf.getStyle()]
;
@@ -133,9 +140,9 @@ class FontLab extends Activity
"Regular", "Bold", "Italic", "Bold Italic"
};
private static final String sTypefaceName[] = {
"Droid Sans",
"Droid Serif",
"Droid Mono"
"Sans",
"Serif",
"Mono"
};
private static final Typeface sTypeface[] = {
Typeface.SANS_SERIF,
@@ -198,6 +205,7 @@ class FontLab extends Activity
int mask = item.getItemId();
mColumn1.setPaintFlags(mColumn1.getPaintFlags() ^ mask);
mColumn2.setPaintFlags(mColumn2.getPaintFlags() ^ mask);
updateTitle();
return true;
}
};
@@ -233,10 +241,11 @@ class FontLab extends Activity
addFontMenu(menu, FONT_INDEX_SANS);
addFontMenu(menu, FONT_INDEX_SERIF);
addFontMenu(menu, FONT_INDEX_MONO);
// addFontMenu(menu, FONT_INDEX_MONO);
addStyleMenu(menu, Typeface.BOLD, 'b');
addStyleMenu(menu, Typeface.ITALIC, 'i');
addFlagMenu(menu, Paint.DEV_KERN_TEXT_FLAG, "DevKern", 'k');
addFlagMenu(menu, Paint.SUBPIXEL_TEXT_FLAG, "SubPixel", 's');
// addFlagMenu(menu, Paint.DEV_KERN_TEXT_FLAG, "DevKern", 'k');
menu.add(0, 0, 0, "Text").setOnMenuItemClickListener(mTextCallback).setAlphabeticShortcut('t');
return true;
@@ -286,14 +295,14 @@ class FontLab extends Activity
case KeyEvent.KEYCODE_DPAD_LEFT:
scaleX -= 1;
break;
/*
case KeyEvent.KEYCODE_U:
case KeyEvent.KEYCODE_VOLUME_UP:
changeGamma(1);
return true;
case KeyEvent.KEYCODE_D:
case KeyEvent.KEYCODE_VOLUME_DOWN:
changeGamma(-1);
return true;
*/
default:
return super.onKeyDown(keyCode, event);
}
@@ -318,16 +327,18 @@ class FontLab extends Activity
return super.onKeyDown(keyCode, event);
}
private int mGamma = 28; // current default is 1.4 (* 20)
// default to gamma of 1.0
private int mGamma = Math.round(1.0f * GAMMA_RANGE);
private void changeGamma(int delta) {
int gamma = Math.min(100, Math.max(1, mGamma + delta));
int gamma = Math.min(MAX_GAMMA, Math.max(MIN_GAMMA, mGamma + delta));
if (gamma != mGamma) {
mGamma = gamma;
updateTitle();
// Paint.setTextGamma(mGamma / 20.f);
float blackGamma = mGamma / GAMMA_RANGE;
Typeface.setGammaForText(blackGamma, 1 / blackGamma);
mContentView.invalidate();
android.util.Log.d("skia", "setTextGamma " + mGamma);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,10 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := NinePatchLab
include $(BUILD_PACKAGE)

View File

@@ -0,0 +1,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.ninepatchlab">
<application android:label="9-patch-lab">
<activity android:name="NinePatchLab">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

190
apps/NinePatchLab/NOTICE Normal file
View File

@@ -0,0 +1,190 @@
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1000 B

View File

@@ -0,0 +1,210 @@
/*
* 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.ninepatchlab;
import com.android.ninepatchlab.R;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.*;
public class NinePatchLab extends Activity {
public NinePatchLab() {}
Drawable[] mButtons;
Drawable[] mBGs;
float mScale;
boolean mShowFPS = true;
boolean mDoDither = true;
boolean mDoFilter = true;
int mCurrBGIndex;
private static final int FPS_COUNTER_LIMIT = 30;
private int mFPSTime;
private int mFPSCounter;
private int mFPSAve;
private View mView;
private void updateTitle() {
String title = "D=" + mDoDither + " F=" + mDoFilter;
if (mShowFPS) {
title += " FPS=" + mFPSAve;
}
setTitle(title);
}
private static Drawable make_custom_bg() {
int[] colors = new int[] {
// 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000
0xFFFF0000, 0xFF0000FF
};
return new GradientDrawable(GradientDrawable.Orientation.TR_BL,
colors);
}
private static Drawable make_solid_bg() {
return new ColorDrawable(0xFF008800);
}
private class NPView extends View {
public NPView(Context context) {
super(context);
setFocusable(true);
int[] bgs = new int[] {
R.drawable.bg_grad_blue,
R.drawable.bg_grad_green,
R.drawable.bg_grad_grey,
R.drawable.bg_grad_red,
R.drawable.bg_grad_yellow,
};
int[] ids = new int[] {
R.drawable.btn_dark_ticks_stretch_multiple,
R.drawable.btn_dark_ticks_stretch_single,
R.drawable.btn_transparent_ticks_stretch_multiple,
R.drawable.btn_transparent_ticks_stretch_single,
R.drawable.btn_light_ticks_stretch_multiple,
R.drawable.btn_light_ticks_stretch_single,
};
mButtons = new Drawable[ids.length];
mBGs = new Drawable[bgs.length + 2];
Resources res = context.getResources();
for (int i = 0; i < ids.length; i++) {
mButtons[i] = res.getDrawable(ids[i]);
}
for (int i = 0; i < bgs.length; i++) {
mBGs[i] = res.getDrawable(bgs[i]);
}
mBGs[bgs.length] = make_custom_bg();
mBGs[bgs.length+1] = make_solid_bg();
mScale = res.getDisplayMetrics().density;
}
private static final int MARGIN_X = 16;
private static final int MARGIN_Y = 8;
private void setDrawableFlags(Drawable dr) {
dr.setDither(mDoDither);
dr.setFilterBitmap(mDoFilter);
}
protected void onDraw(Canvas canvas) {
long now = 0;
if (mShowFPS) {
now = SystemClock.uptimeMillis();
}
Drawable bg = mBGs[mCurrBGIndex];
bg.setBounds(0, 0, getWidth(), getHeight());
setDrawableFlags(bg);
bg.draw(canvas);
final int WIDTH = getWidth() - 2*MARGIN_X;
final int HEIGHT = getHeight() - 2*MARGIN_Y;
final int N = mButtons.length;
final int gapSize = Math.round(mScale * 8);
final int drHeight = (HEIGHT - (N - 1) * gapSize) / N;
final int drWidth = WIDTH;
// canvas.drawColor(0xFF5F810C);
canvas.translate(MARGIN_X, MARGIN_Y);
for (Drawable dr : mButtons) {
dr.setBounds(0, 0, drWidth, drHeight);
setDrawableFlags(dr);
dr.draw(canvas);
canvas.translate(0, drHeight + gapSize);
}
if (mShowFPS) {
mFPSTime += (int)(SystemClock.uptimeMillis() - now);
mFPSCounter += 1;
if (mFPSCounter > FPS_COUNTER_LIMIT) {
mFPSAve = mFPSCounter * 1000 / mFPSTime;
updateTitle();
mFPSTime = 0;
mFPSCounter = 0;
}
invalidate();
}
}
}
private void toggleFPS() {
mShowFPS = !mShowFPS;
if (mShowFPS) {
mFPSCounter = 0;
mFPSTime = 0;
mView.invalidate();
}
}
@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:
mDoFilter = !mDoFilter;
updateTitle();
mView.invalidate();
return true;
case KeyEvent.KEYCODE_DPAD_UP:
mDoDither = !mDoDither;
updateTitle();
mView.invalidate();
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
mCurrBGIndex = (mCurrBGIndex + 1) % mBGs.length;
mView.invalidate();
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
mCurrBGIndex -= 1;
if (mCurrBGIndex < 0) {
mCurrBGIndex = 0;
}
mView.invalidate();
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
toggleFPS();
return true;
case KeyEvent.KEYCODE_U:
case KeyEvent.KEYCODE_D:
case KeyEvent.KEYCODE_VOLUME_DOWN:
return super.onKeyDown(keyCode, event);
}
return super.onKeyDown(keyCode, event);
}
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mView = new NPView(this);
setContentView(mView);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,3 +1,26 @@
#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This makefile shows how to build a shared library and an activity that
# bundles the shared library and calls it using JNI.
TOP_LOCAL_PATH:= $(call my-dir)
# Build activity
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -7,4 +30,11 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := Term
LOCAL_JNI_SHARED_LIBRARIES := libterm
include $(BUILD_PACKAGE)
# ============================================================
# Also build all of the sub-targets under this one: the shared library.
include $(call all-makefiles-under,$(LOCAL_PATH))

54
apps/Term/jni/Android.mk Normal file
View File

@@ -0,0 +1,54 @@
#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This makefile supplies the rules for building a library of JNI code for
# use by our example of how to bundle a shared library with an APK.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
# This is the target being built.
LOCAL_MODULE:= libterm
# All of the source files that we will compile.
LOCAL_SRC_FILES:= \
termExec.cpp
# All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES := \
libutils
# No static libraries.
LOCAL_STATIC_LIBRARIES :=
# Also need the JNI headers.
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE)
# No special compiler flags.
LOCAL_CFLAGS +=
# Don't prelink this library. For more efficient code, you may want
# to add this library to the prelink map and set this to true. However,
# it's difficult to do this for applications that are not supplied as
# part of a system image.
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)

347
apps/Term/jni/termExec.cpp Normal file
View File

@@ -0,0 +1,347 @@
/*
* 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.
*/
/*
* 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.
*/
#define LOG_TAG "Exec"
#include "jni.h"
#include "utils/Log.h"
#include "utils/misc.h"
#include "android_runtime/AndroidRuntime.h"
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
static jclass class_fileDescriptor;
static jfieldID field_fileDescriptor_descriptor;
static jmethodID method_fileDescriptor_init;
class String8 {
public:
String8() {
mString = 0;
}
~String8() {
if (mString) {
free(mString);
}
}
void set(const char16_t* o, size_t numChars) {
mString = (char*) malloc(numChars + 1);
for (size_t i = 0; i < numChars; i++) {
mString[i] = (char) o[i];
}
mString[numChars] = '\0';
}
const char* string() {
return mString;
}
private:
char* mString;
};
static int create_subprocess(const char *cmd, const char *arg0, const char *arg1,
int* pProcessId)
{
char *devname;
int ptm;
pid_t pid;
ptm = open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
if(ptm < 0){
LOGE("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
return -1;
}
fcntl(ptm, F_SETFD, FD_CLOEXEC);
if(grantpt(ptm) || unlockpt(ptm) ||
((devname = (char*) ptsname(ptm)) == 0)){
LOGE("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
return -1;
}
pid = fork();
if(pid < 0) {
LOGE("- fork failed: %s -\n", strerror(errno));
return -1;
}
if(pid == 0){
close(ptm);
int pts;
setsid();
pts = open(devname, O_RDWR);
if(pts < 0) exit(-1);
dup2(pts, 0);
dup2(pts, 1);
dup2(pts, 2);
execl(cmd, cmd, arg0, arg1, NULL);
exit(-1);
} else {
*pProcessId = (int) pid;
return ptm;
}
}
static jobject android_os_Exec_createSubProcess(JNIEnv *env, jobject clazz,
jstring cmd, jstring arg0, jstring arg1, jintArray processIdArray)
{
const jchar* str = cmd ? env->GetStringCritical(cmd, 0) : 0;
String8 cmd_8;
if (str) {
cmd_8.set(str, env->GetStringLength(cmd));
env->ReleaseStringCritical(cmd, str);
}
str = arg0 ? env->GetStringCritical(arg0, 0) : 0;
const char* arg0Str = 0;
String8 arg0_8;
if (str) {
arg0_8.set(str, env->GetStringLength(arg0));
env->ReleaseStringCritical(arg0, str);
arg0Str = arg0_8.string();
}
str = arg1 ? env->GetStringCritical(arg1, 0) : 0;
const char* arg1Str = 0;
String8 arg1_8;
if (str) {
arg1_8.set(str, env->GetStringLength(arg1));
env->ReleaseStringCritical(arg1, str);
arg1Str = arg1_8.string();
}
int procId;
int ptm = create_subprocess(cmd_8.string(), arg0Str, arg1Str, &procId);
if (processIdArray) {
int procIdLen = env->GetArrayLength(processIdArray);
if (procIdLen > 0) {
jboolean isCopy;
int* pProcId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy);
if (pProcId) {
*pProcId = procId;
env->ReleasePrimitiveArrayCritical(processIdArray, pProcId, 0);
}
}
}
jobject result = env->NewObject(class_fileDescriptor, method_fileDescriptor_init);
if (!result) {
LOGE("Couldn't create a FileDescriptor.");
}
else {
env->SetIntField(result, field_fileDescriptor_descriptor, ptm);
}
return result;
}
static void android_os_Exec_setPtyWindowSize(JNIEnv *env, jobject clazz,
jobject fileDescriptor, jint row, jint col, jint xpixel, jint ypixel)
{
int fd;
struct winsize sz;
fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
if (env->ExceptionOccurred() != NULL) {
return;
}
sz.ws_row = row;
sz.ws_col = col;
sz.ws_xpixel = xpixel;
sz.ws_ypixel = ypixel;
ioctl(fd, TIOCSWINSZ, &sz);
}
static int android_os_Exec_waitFor(JNIEnv *env, jobject clazz,
jint procId) {
int status;
waitpid(procId, &status, 0);
int result = 0;
if (WIFEXITED(status)) {
result = WEXITSTATUS(status);
}
return result;
}
static void android_os_Exec_close(JNIEnv *env, jobject clazz, jobject fileDescriptor)
{
int fd;
struct winsize sz;
fd = env->GetIntField(fileDescriptor, field_fileDescriptor_descriptor);
if (env->ExceptionOccurred() != NULL) {
return;
}
close(fd);
}
static int register_FileDescriptor(JNIEnv *env)
{
class_fileDescriptor = env->FindClass("java/io/FileDescriptor");
if (class_fileDescriptor == NULL) {
LOGE("Can't find java/io/FileDescriptor");
return -1;
}
field_fileDescriptor_descriptor = env->GetFieldID(class_fileDescriptor, "descriptor", "I");
if (field_fileDescriptor_descriptor == NULL) {
LOGE("Can't find FileDescriptor.descriptor");
return -1;
}
method_fileDescriptor_init = env->GetMethodID(class_fileDescriptor, "<init>", "()V");
if (method_fileDescriptor_init == NULL) {
LOGE("Can't find FileDescriptor.init");
return -1;
}
return 0;
}
static const char *classPathName = "com/android/term/Exec";
static JNINativeMethod method_table[] = {
{ "createSubprocess", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I)Ljava/io/FileDescriptor;",
(void*) android_os_Exec_createSubProcess },
{ "setPtyWindowSize", "(Ljava/io/FileDescriptor;IIII)V",
(void*) android_os_Exec_setPtyWindowSize},
{ "waitFor", "(I)I",
(void*) android_os_Exec_waitFor},
{ "close", "(Ljava/io/FileDescriptor;)V",
(void*) android_os_Exec_close}
};
/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
LOGE("Native registration unable to find class '%s'", className);
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
LOGE("RegisterNatives failed for '%s'", className);
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* Register native methods for all classes we know about.
*
* returns JNI_TRUE on success.
*/
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, classPathName, method_table,
sizeof(method_table) / sizeof(method_table[0]))) {
return JNI_FALSE;
}
return JNI_TRUE;
}
// ----------------------------------------------------------------------------
/*
* This is called by the VM when the shared library is first loaded.
*/
typedef union {
JNIEnv* env;
void* venv;
} UnionJNIEnvToVoid;
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
UnionJNIEnvToVoid uenv;
uenv.venv = NULL;
jint result = -1;
JNIEnv* env = NULL;
LOGI("JNI_OnLoad");
if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
LOGE("ERROR: GetEnv failed");
goto bail;
}
env = uenv.env;
if ((result = register_FileDescriptor(env)) < 0) {
LOGE("ERROR: registerFileDescriptor failed");
goto bail;
}
if (registerNatives(env) != JNI_TRUE) {
LOGE("ERROR: registerNatives failed");
goto bail;
}
result = JNI_VERSION_1_4;
bail:
return result;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 1006 B

View File

@@ -0,0 +1,75 @@
/*
* 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.
*/
package com.android.term;
import java.io.FileDescriptor;
/**
* Utility methods for creating and managing a subprocess.
* <p>
* Note: The native methods access a package-private
* java.io.FileDescriptor field to get and set the raw Linux
* file descriptor. This might break if the implementation of
* java.io.FileDescriptor is changed.
*/
public class Exec
{
static {
System.loadLibrary("term");
}
/**
* Create a subprocess. Differs from java.lang.ProcessBuilder in
* that a pty is used to communicate with the subprocess.
* <p>
* Callers are responsible for calling Exec.close() on the returned
* file descriptor.
*
* @param cmd The command to execute
* @param arg0 The first argument to the command, may be null
* @param arg1 the second argument to the command, may be null
* @param processId A one-element array to which the process ID of the
* started process will be written.
* @return the file descriptor of the started process.
*
*/
public static native FileDescriptor createSubprocess(
String cmd, String arg0, String arg1, int[] processId);
/**
* Set the widow size for a given pty. Allows programs
* connected to the pty learn how large their screen is.
*/
public static native void setPtyWindowSize(FileDescriptor fd,
int row, int col, int xpixel, int ypixel);
/**
* Causes the calling thread to wait for the process associated with the
* receiver to finish executing.
*
* @return The exit value of the Process being waited on
*
*/
public static native int waitFor(int processId);
/**
* Close a given file descriptor.
*/
public static native void close(FileDescriptor fd);
}

View File

@@ -16,6 +16,12 @@
package com.android.term;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
@@ -35,7 +41,6 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Exec;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
@@ -54,12 +59,6 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
/**
* A terminal emulator activity.
*/
@@ -96,10 +95,7 @@ public class Term extends Activity {
/**
* The pseudo-teletype (pty) file descriptor that we use to communicate with
* another process, typically a shell. Currently we just use this to get the
* mTermIn / mTermOut file descriptors, but when we implement resizing of
* the terminal we will need it to issue the ioctl to inform the other
* process that we've changed the terminal size.
* another process, typically a shell.
*/
private FileDescriptor mTermFd;
@@ -188,6 +184,15 @@ public class Term extends Activity {
updatePrefs();
}
@Override
public void onDestroy() {
super.onDestroy();
if (mTermFd != null) {
Exec.close(mTermFd);
mTermFd = null;
}
}
private void startListening() {
int[] processId = new int[1];

View File

@@ -4,7 +4,7 @@ LOCAL_PATH := $(call my-dir)
# anywhere else, and the rules don't support. Aditionally, the depenencies on
# these files don't really matter, because they are all generated as part of
# building the docs. So for the dependency, we just use the
# offline-sdk-timestamp file, which is the $@ of the droiddoc rule.
# api-stubs-timestamp file, which is the $@ of the droiddoc rule.
# We also need to depend on framework-res.apk, in order to pull the
# resource files out of there for aapt.
#
@@ -22,7 +22,7 @@ $(full_target): PRIVATE_INTERMEDIATES_DIR := $(intermediates)
$(full_target): PRIVATE_CLASS_INTERMEDIATES_DIR := $(classes_dir)
$(full_target): PRIVATE_FRAMEWORK_RES_PACKAGE := $(framework_res_package)
$(full_target): $(OUT_DOCS)/offline-sdk-timestamp $(framework_res_package)
$(full_target): $(OUT_DOCS)/api-stubs-timestamp $(framework_res_package)
@echo Compiling SDK Stubs: $@
$(hide) rm -rf $(PRIVATE_CLASS_INTERMEDIATES_DIR)
$(hide) mkdir -p $(PRIVATE_CLASS_INTERMEDIATES_DIR)

View File

@@ -3,6 +3,7 @@
# swt
prebuilt/darwin-x86/swt/swt.jar tools/lib/x86/swt.jar
prebuilt/darwin-x86_64/swt/swt.jar tools/lib/x86_64/swt.jar
# JetCreator (only available on mac/windows)

View File

@@ -51,15 +51,17 @@ obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl
# sdk scripts
development/tools/scripts/AndroidManifest.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.template
development/tools/scripts/AndroidManifest.tests.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.tests.template
development/tools/scripts/iml.template platforms/${PLATFORM_NAME}/templates/iml.template
development/tools/scripts/ipr.template platforms/${PLATFORM_NAME}/templates/ipr.template
development/tools/scripts/iws.template platforms/${PLATFORM_NAME}/templates/iws.template
development/tools/scripts/java_file.template platforms/${PLATFORM_NAME}/templates/java_file.template
development/tools/scripts/java_tests_file.template platforms/${PLATFORM_NAME}/templates/java_tests_file.template
development/tools/scripts/layout.template platforms/${PLATFORM_NAME}/templates/layout.template
development/tools/scripts/strings.template platforms/${PLATFORM_NAME}/templates/strings.template
development/tools/scripts/android_rules.xml platforms/${PLATFORM_NAME}/templates/android_rules.xml
development/tools/scripts/android_test_rules.xml platforms/${PLATFORM_NAME}/templates/android_test_rules.xml
development/tools/scripts/icon_ldpi.png platforms/${PLATFORM_NAME}/templates/icon_ldpi.png
development/tools/scripts/icon_mdpi.png platforms/${PLATFORM_NAME}/templates/icon_mdpi.png
development/tools/scripts/icon_hdpi.png platforms/${PLATFORM_NAME}/templates/icon_hdpi.png
development/tools/scripts/build.template tools/lib/build.template
development/tools/scripts/devices.xml tools/lib/devices.xml
# emacs support
development/tools/scripts/android.el tools/lib/android.el
@@ -121,10 +123,21 @@ bin/draw9patch tools/draw9patch
framework/draw9patch.jar tools/lib/draw9patch.jar
framework/swing-worker-1.1.jar tools/lib/swing-worker-1.1.jar
# layoutopt
bin/layoutopt tools/layoutopt
framework/layoutopt.jar tools/lib/layoutopt.jar
framework/uix.jar tools/lib/uix.jar
framework/groovy-all-1.6.5.jar tools/lib/groovy-all-1.6.5.jar
# traceview
bin/traceview tools/traceview
framework/traceview.jar tools/lib/traceview.jar
# emma lib for code coverage support
framework/emmalib.jar tools/lib/emma_device.jar
external/emma/lib/emma.jar tools/lib/emma.jar
external/emma/lib/emma_ant.jar tools/lib/emma_ant.jar
# custom ant tasks
framework/anttasks.jar tools/lib/anttasks.jar
@@ -144,10 +157,12 @@ prebuilt/android-arm/kernel/kernel-qemu platforms/${PLATFORM_NAME}/images/kernel
external/qemu/android/avd/hardware-properties.ini tools/lib/hardware-properties.ini
# emulator skins
development/emulator/skins/HVGA platforms/${PLATFORM_NAME}/skins/HVGA
development/emulator/skins/QVGA platforms/${PLATFORM_NAME}/skins/QVGA
development/emulator/skins/WVGA800 platforms/${PLATFORM_NAME}/skins/WVGA800
development/emulator/skins/WVGA854 platforms/${PLATFORM_NAME}/skins/WVGA854
development/emulator/skins/QVGA platforms/${PLATFORM_NAME}/skins/QVGA
development/emulator/skins/WQVGA432 platforms/${PLATFORM_NAME}/skins/WQVGA432
development/emulator/skins/WQVGA400 platforms/${PLATFORM_NAME}/skins/WQVGA400
development/emulator/skins/HVGA platforms/${PLATFORM_NAME}/skins/HVGA
development/emulator/skins/WVGA800 platforms/${PLATFORM_NAME}/skins/WVGA800
development/emulator/skins/WVGA854 platforms/${PLATFORM_NAME}/skins/WVGA854
# NOTICE files are copied by build/core/Makefile
development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/templates/NOTICE.txt
@@ -171,16 +186,21 @@ docs/service_actions.txt platforms/${PLATFORM_NAME}/data/service_actions.txt
docs/categories.txt platforms/${PLATFORM_NAME}/data/categories.txt
docs/widgets.txt platforms/${PLATFORM_NAME}/data/widgets.txt
framework/layoutlib.jar platforms/${PLATFORM_NAME}/data/layoutlib.jar
# framework resources for layoutlib
frameworks/base/core/res/res platforms/${PLATFORM_NAME}/data/res
frameworks/base/data/fonts/fonts.xml platforms/${PLATFORM_NAME}/data/fonts/fonts.xml
frameworks/base/data/fonts/DroidSans.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSans.ttf
frameworks/base/data/fonts/DroidSans-Bold.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSans-Bold.ttf
frameworks/base/data/fonts/DroidSansFallback.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSansFallback.ttf
frameworks/base/data/fonts/DroidSansMono.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSansMono.ttf
frameworks/base/data/fonts/DroidSerif-Bold.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Bold.ttf
# fonts for layoutlib.
frameworks/base/data/fonts/fonts.xml platforms/${PLATFORM_NAME}/data/fonts/fonts.xml
frameworks/base/data/fonts/DroidSans.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSans.ttf
frameworks/base/data/fonts/DroidSans-Bold.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSans-Bold.ttf
frameworks/base/data/fonts/DroidSansMono.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSansMono.ttf
frameworks/base/data/fonts/DroidSerif-Bold.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Bold.ttf
frameworks/base/data/fonts/DroidSerif-BoldItalic.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-BoldItalic.ttf
frameworks/base/data/fonts/DroidSerif-Italic.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Italic.ttf
frameworks/base/data/fonts/DroidSerif-Regular.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Regular.ttf
frameworks/base/data/fonts/DroidSerif-Italic.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Italic.ttf
frameworks/base/data/fonts/DroidSerif-Regular.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSerif-Regular.ttf
frameworks/base/data/fonts/DroidSansFallback.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSansFallback.ttf
frameworks/base/data/fonts/DroidSansJapanese.ttf platforms/${PLATFORM_NAME}/data/fonts/DroidSansJapanese.ttf
# empty add-on folder with just a readme
development/tools/scripts/README_add-ons.txt add-ons/README.txt

View File

@@ -99,7 +99,7 @@ function build() {
fastboot \
hprof-conv \
mksdcard \
sqlite3 \
sdklauncher sqlite3 \
zipalign \
|| die "Build failed"
}
@@ -141,7 +141,7 @@ function package() {
TOOLS="$TEMP_SDK_DIR/tools"
LIB="$TEMP_SDK_DIR/tools/lib"
rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator}
rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,mksdcard,sqlite3,traceview,zipalign}
rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,layoutopt,mksdcard,sqlite3,traceview,zipalign}
rm -v "$LIB"/*/swt.jar
rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
@@ -153,6 +153,9 @@ function package() {
mkdir -pv "$LIB"/x86_64
cp -v prebuilt/windows-x86_64/swt/swt.jar "$LIB"/x86_64/
# Move the SDK Setup (aka sdklauncher) to the root of the SDK (it was copied in tools above)
mv "$TOOLS/sdklauncher.exe" "$TEMP_SDK_DIR/SDK Setup.exe"
# If you want the emulator NOTICE in the tools dir, uncomment the following line:
# cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
@@ -164,6 +167,7 @@ function package() {
cp -v development/tools/ddms/app/etc/ddms.bat "$TOOLS"/
cp -v development/tools/traceview/etc/traceview.bat "$TOOLS"/
cp -v development/tools/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"/
cp -v development/tools/layoutopt/app/etc/layoutopt.bat "$TOOLS"/
cp -v development/tools/draw9patch/etc/draw9patch.bat "$TOOLS"/
cp -v development/tools/sdkmanager/app/etc/android.bat "$TOOLS"/

View File

@@ -40,7 +40,7 @@ public class MonkeyNetworkMonitor extends IIntentReceiver.Stub {
private long mElapsedTime = 0; // amount of time spent between start() and stop()
public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
boolean ordered) throws RemoteException {
boolean ordered, boolean sticky) throws RemoteException {
NetworkInfo ni = (NetworkInfo) intent.getParcelableExtra(
ConnectivityManager.EXTRA_NETWORK_INFO);
if (LDEBUG) System.out.println("Network state changed: "

View File

@@ -16,6 +16,7 @@
package com.android.commands.monkey;
import android.content.ComponentName;
import android.os.SystemClock;
import android.view.KeyEvent;
@@ -28,6 +29,7 @@ import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;
import android.view.KeyEvent;
/**
* monkey event queue. It takes a script to produce events
*
@@ -52,6 +54,8 @@ public class MonkeySourceScript implements MonkeyEventSource {
private static final String HEADER_TYPE = "type=";
private static final String HEADER_COUNT = "count=";
private static final String HEADER_SPEED = "speed=";
// New script type
private static final String USER_EVENT_TYPE = "user";
private long mLastRecordedDownTimeKey = 0;
private long mLastRecordedDownTimeMotion = 0;
@@ -59,6 +63,7 @@ public class MonkeySourceScript implements MonkeyEventSource {
private long mLastExportDownTimeMotion = 0;
private long mLastExportEventTime = -1;
private long mLastRecordedEventTime = -1;
private String mScriptType = USER_EVENT_TYPE;
private static final boolean THIS_DEBUG = false;
// a parameter that compensates the difference of real elapsed time and
@@ -77,10 +82,15 @@ public class MonkeySourceScript implements MonkeyEventSource {
private static final String EVENT_KEYWORD_TRACKBALL = "DispatchTrackball";
private static final String EVENT_KEYWORD_KEY = "DispatchKey";
private static final String EVENT_KEYWORD_FLIP = "DispatchFlip";
private static final String EVENT_KEYWORD_KEYPRESS = "DispatchPress";
private static final String EVENT_KEYWORD_ACTIVITY = "LaunchActivity";
private static final String EVENT_KEYWORD_WAIT = "UserWait";
private static final String EVENT_KEYWORD_LONGPRESS = "LongPress";
// a line at the end of the header
private static final String STARTING_DATA_LINE = "start data >>";
private boolean mFileOpened = false;
private static int LONGPRESS_WAIT_TIME = 2000; // wait time for the long press
FileInputStream mFStream;
DataInputStream mInputStream;
@@ -125,7 +135,7 @@ public class MonkeySourceScript implements MonkeyEventSource {
while ((sLine = mBufferReader.readLine()) != null) {
sLine = sLine.trim();
if (sLine.indexOf(HEADER_TYPE) >= 0) {
// at this point, we only have one type of script
mScriptType = sLine.substring(HEADER_TYPE.length() + 1).trim();
} else if (sLine.indexOf(HEADER_COUNT) >= 0) {
try {
mEventCountInScript = Integer.parseInt(sLine.substring(
@@ -161,21 +171,12 @@ public class MonkeySourceScript implements MonkeyEventSource {
}
return false;
}
private void processLine(String s) {
int index1 = s.indexOf('(');
int index2 = s.indexOf(')');
if (index1 < 0 || index2 < 0) {
return;
}
StringTokenizer st = new StringTokenizer(
s.substring(index1 + 1, index2), ",");
private void handleRawEvent(String s, StringTokenizer st) {
if (s.indexOf(EVENT_KEYWORD_KEY) >= 0) {
// key events
try {
System.out.println(" old key\n");
long downTime = Long.parseLong(st.nextToken());
long eventTime = Long.parseLong(st.nextToken());
int action = Integer.parseInt(st.nextToken());
@@ -184,18 +185,22 @@ public class MonkeySourceScript implements MonkeyEventSource {
int metaState = Integer.parseInt(st.nextToken());
int device = Integer.parseInt(st.nextToken());
int scancode = Integer.parseInt(st.nextToken());
MonkeyKeyEvent e = new MonkeyKeyEvent(downTime, eventTime,
action, code, repeat, metaState, device, scancode);
MonkeyKeyEvent e =
new MonkeyKeyEvent(downTime, eventTime, action, code, repeat, metaState,
device, scancode);
System.out.println(" Key code " + code + "\n");
mQ.addLast(e);
System.out.println("Added key up \n");
} catch (NumberFormatException e) {
// something wrong with this line in the script
// something wrong with this line in the script
}
} else if (s.indexOf(EVENT_KEYWORD_POINTER) >= 0 ||
s.indexOf(EVENT_KEYWORD_TRACKBALL) >= 0) {
// trackball/pointer event
try {
// trackball/pointer event
try {
long downTime = Long.parseLong(st.nextToken());
long eventTime = Long.parseLong(st.nextToken());
int action = Integer.parseInt(st.nextToken());
@@ -208,25 +213,78 @@ public class MonkeySourceScript implements MonkeyEventSource {
float yPrecision = Float.parseFloat(st.nextToken());
int device = Integer.parseInt(st.nextToken());
int edgeFlags = Integer.parseInt(st.nextToken());
int type = MonkeyEvent.EVENT_TYPE_TRACKBALL;
int type = MonkeyEvent.EVENT_TYPE_TRACKBALL;
if (s.indexOf("Pointer") > 0) {
type = MonkeyEvent.EVENT_TYPE_POINTER;
}
MonkeyMotionEvent e = new MonkeyMotionEvent(type, downTime, eventTime,
action, x, y, pressure, size, metaState, xPrecision, yPrecision,
device, edgeFlags);
mQ.addLast(e);
}
MonkeyMotionEvent e =
new MonkeyMotionEvent(type, downTime, eventTime, action, x, y, pressure,
size, metaState, xPrecision, yPrecision, device, edgeFlags);
mQ.addLast(e);
} catch (NumberFormatException e) {
// we ignore this event
// we ignore this event
}
} else if (s.indexOf(EVENT_KEYWORD_FLIP) >= 0) {
boolean keyboardOpen = Boolean.parseBoolean(st.nextToken());
MonkeyFlipEvent e = new MonkeyFlipEvent(keyboardOpen);
mQ.addLast(e);
}
}
private void handleUserEvent(String s, StringTokenizer st) {
if (s.indexOf(EVENT_KEYWORD_ACTIVITY) >= 0) {
String pkg_name = st.nextToken();
String cl_name = st.nextToken();
ComponentName mApp = new ComponentName(pkg_name, cl_name);
MonkeyActivityEvent e = new MonkeyActivityEvent(mApp);
mQ.addLast(e);
} else if (s.indexOf(EVENT_KEYWORD_WAIT) >= 0) {
long sleeptime = Integer.parseInt(st.nextToken());
MonkeyWaitEvent e = new MonkeyWaitEvent(sleeptime);
mQ.addLast(e);
} else if (s.indexOf(EVENT_KEYWORD_KEYPRESS) >= 0) {
String key_name = st.nextToken();
int keyCode = MonkeySourceRandom.getKeyCode(key_name);
MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, keyCode);
mQ.addLast(e);
e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, keyCode);
mQ.addLast(e);
} else if (s.indexOf(EVENT_KEYWORD_LONGPRESS) >= 0) {
// handle the long press
MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_DPAD_CENTER);
mQ.addLast(e);
MonkeyWaitEvent we = new MonkeyWaitEvent(LONGPRESS_WAIT_TIME);
mQ.addLast(we);
e = new MonkeyKeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_DPAD_CENTER);
mQ.addLast(e);
}
}
private void processLine(String s) {
int index1 = s.indexOf('(');
int index2 = s.indexOf(')');
if (index1 < 0 || index2 < 0) {
return;
}
StringTokenizer st = new StringTokenizer(
s.substring(index1 + 1, index2), ",");
if (mScriptType.compareTo(USER_EVENT_TYPE) == 0) {
// User event type
handleUserEvent(s, st);
} else {
// Raw type
handleRawEvent(s,st);
}
}
private void closeFile() {
mFileOpened = false;
if (THIS_DEBUG) {
@@ -253,31 +311,27 @@ public class MonkeySourceScript implements MonkeyEventSource {
}
/**
* read next batch of events from the provided script file
* read next batch of events from the provided script file
* @return true if success
*/
private boolean readNextBatch() {
/*
* The script should restore the original state when it run multiple
* times.
*/
String sLine = null;
int readCount = 0;
if (THIS_DEBUG) {
System.out.println("readNextBatch(): reading next batch of events");
}
if (!mFileOpened) {
if (!readScriptHeader()) {
closeFile();
return false;
}
}
resetValue();
/*
* In order to allow the Monkey to replay captured events multiple times
* we need to define a default start UI, which is the home screen
* Otherwise, it won't be accurate since the captured events
* could end anywhere
*/
addHomeKeyEvent();
}
try {
@@ -418,7 +472,6 @@ public class MonkeySourceScript implements MonkeyEventSource {
}
MonkeyEvent e = mQ.getFirst();
mQ.removeFirst();
if (e.getEventType() == MonkeyEvent.EVENT_TYPE_KEY) {
adjustKeyEventTime((MonkeyKeyEvent) e);
} else if (e.getEventType() == MonkeyEvent.EVENT_TYPE_POINTER ||

View File

@@ -0,0 +1,48 @@
/*
* 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.commands.monkey;
import android.app.IActivityManager;
import android.view.IWindowManager;
/**
* monkey throttle event
*/
public class MonkeyWaitEvent extends MonkeyEvent {
private long mWaitTime;
public MonkeyWaitEvent(long waitTime) {
super(MonkeyEvent.EVENT_TYPE_THROTTLE);
mWaitTime = waitTime;
}
@Override
public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
if (verbose > 1) {
System.out.println("Wait Event for " + mWaitTime + " milliseconds");
}
try {
Thread.sleep(mWaitTime);
} catch (InterruptedException e1) {
System.out.println("** Monkey interrupted in sleep.");
return MonkeyEvent.INJECT_FAIL;
}
return MonkeyEvent.INJECT_SUCCESS;
}
}

View File

@@ -1,6 +1,7 @@
key 164 MEDIA_PLAY_PAUSE WAKE
key 128 MEDIA_STOP WAKE
key 200 MEDIA_PLAY_PAUSE WAKE
key 201 MEDIA_PLAY_PAUSE WAKE
key 166 MEDIA_STOP WAKE
key 163 MEDIA_NEXT WAKE
key 165 MEDIA_PREVIOUS WAKE
key 168 MEDIA_REWIND WAKE
key 159 MEDIA_FAST_FORWARD WAKE
key 208 MEDIA_FAST_FORWARD WAKE

View File

@@ -18,7 +18,7 @@ parts {
y 0
}
}
controls {
background {
image controls.png
@@ -357,7 +357,7 @@ layouts {
height 534
color 0xe0e0e0
event EV_SW:0:1
part1 {
name portrait
x 0
@@ -394,6 +394,12 @@ layouts {
color 0xe0e0e0
event EV_SW:0:0
# the framework _always_ assume that the DPad
# has been physically rotated in landscape mode.
# however, with this skin, this is not the case
#
dpad-rotation 3
part1 {
name portrait
x 800

View File

@@ -393,6 +393,9 @@ layouts {
color 0xe0e0e0
event EV_SW:0:0
dpad-rotation 3
part1 {
name portrait
x 800

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,2 @@
# skin-specific hardware values
hw.lcd.density=120

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,438 @@
parts {
portrait {
background {
image background_port.png
}
}
landscape {
background {
image background_land.png
}
}
device {
display {
width 240
height 400
x 0
y 0
}
}
controls {
background {
image controls.png
}
buttons {
soft-left {
image button.png
x 56
y 142
}
home {
image button.png
x 0
y 142
}
back {
image button.png
x 112
y 142
}
dpad-up {
image arrow_up.png
x 77
y 53
}
dpad-down {
image arrow_down.png
x 77
y 106
}
dpad-left {
image arrow_left.png
x 53
y 53
}
dpad-right {
image arrow_right.png
x 123
y 53
}
dpad-center {
image select.png
x 77
y 81
}
phone-dial {
image button.png
x 0
y 71
}
phone-hangup {
image button.png
x 168
y 71
}
power {
image button.png
x 168
y 0
}
volume-up {
image button.png
x 112
y 0
}
volume-down {
image button.png
x 56
y 0
}
search {
image button.png
x 168
y 142
}
}
}
keyboard {
background {
image keyboard.png
}
buttons {
1 {
image key.png
x 5
y 5
}
2 {
image key.png
x 42
y 5
}
3 {
image key.png
x 79
y 5
}
4 {
image key.png
x 116
y 5
}
5 {
image key.png
x 153
y 5
}
6 {
image key.png
x 190
y 5
}
7 {
image key.png
x 227
y 5
}
8 {
image key.png
x 264
y 5
}
9 {
image key.png
x 301
y 5
}
0 {
image key.png
x 338
y 5
}
q {
image key.png
x 5
y 41
}
w {
image key.png
x 42
y 41
}
e {
image key.png
x 79
y 41
}
r {
image key.png
x 116
y 41
}
t {
image key.png
x 153
y 41
}
y {
image key.png
x 190
y 41
}
u {
image key.png
x 227
y 41
}
i {
image key.png
x 264
y 41
}
o {
image key.png
x 301
y 41
}
p {
image key.png
x 338
y 41
}
a {
image key.png
x 5
y 77
}
s {
image key.png
x 42
y 77
}
d {
image key.png
x 79
y 77
}
f {
image key.png
x 116
y 77
}
g {
image key.png
x 153
y 77
}
h {
image key.png
x 190
y 77
}
j {
image key.png
x 227
y 77
}
k {
image key.png
x 264
y 77
}
l {
image key.png
x 301
y 77
}
DEL {
image key.png
x 338
y 77
}
CAP {
image key.png
x 5
y 113
}
z {
image key.png
x 42
y 113
}
x {
image key.png
x 79
y 113
}
c {
image key.png
x 116
y 113
}
v {
image key.png
x 153
y 113
}
b {
image key.png
x 190
y 113
}
n {
image key.png
x 227
y 113
}
m {
image key.png
x 264
y 113
}
PERIOD {
image key.png
x 301
y 113
}
ENTER {
image key.png
x 338
y 113
}
ALT {
image key.png
x 5
y 149
}
SYM {
image key.png
x 42
y 149
}
AT {
image key.png
x 79
y 149
}
SPACE {
image spacebar.png
x 116
y 149
}
SLASH {
image key.png
x 264
y 149
}
COMMA {
image key.png
x 301
y 149
}
ALT2 {
image key.png
x 338
y 149
}
}
}
}
layouts {
portrait {
width 711
height 454
color 0xe0e0e0
event EV_SW:0:1
part1 {
name portrait
x 0
y 0
}
part2 {
name landscape
x 800
y 0
}
part3 {
name device
x 28
y 27
}
part4 {
name controls
x 396
y 37
}
part5 {
name keyboard
x 315
y 248
}
}
landscape {
width 640
height 522
color 0xe0e0e0
event EV_SW:0:0
dpad-rotation 3
part1 {
name portrait
x 800
y 0
}
part2 {
name landscape
x 0
y 0
}
part3 {
name device
x 120
y 270
rotation 3
}
part4 {
name controls
x 410
y 317
}
part5 {
name keyboard
x 18
y 317
}
}
}
keyboard {
charmap qwerty2
}
network {
speed full
delay none
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

View File

@@ -393,6 +393,8 @@ layouts {
color 0xe0e0e0
event EV_SW:0:0
dpad-rotation 3
part1 {
name portrait
x 800

View File

@@ -1,2 +1,3 @@
# skin-specific hardware values
hw.lcd.density=240
hw.lcd.density=240
vm.heapSize=24

View File

@@ -394,6 +394,8 @@ layouts {
color 0xe0e0e0
event EV_SW:0:0
dpad-rotation 3
part1 {
name portrait
x 900

View File

@@ -1,2 +1,3 @@
# skin-specific hardware values
hw.lcd.density=240
hw.lcd.density=240
vm.heapSize=24

View File

@@ -394,6 +394,8 @@ layouts {
color 0xe0e0e0
event EV_SW:0:0
dpad-rotation 3
part1 {
name portrait
x 900

View File

@@ -3,12 +3,12 @@
;
[Version]
Signature = "$Windows NT$"
Class = AndroidUsbDeviceClass
ClassGuid = {3F966BD9-FA04-4ec5-991C-D326973B5128}
Class = AndroidUsbDeviceClass
ClassGuid = {3F966BD9-FA04-4ec5-991C-D326973B5128}
Provider = %ProviderName%
DriverVer = 08/11/2009,2.0.0010.00002
CatalogFile.NTx86 = androidwinusb86.cat
CatalogFile.NTamd64 = androidwinusba64.cat
DriverVer = 08/11/2009,2.0.0010.00002
CatalogFile.NTx86 = androidwinusb86.cat
CatalogFile.NTamd64 = androidwinusba64.cat
;
; This section seems to be required for WinUsb driver installation.
@@ -32,6 +32,13 @@ HKR,,Icon,,-1
%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0FFF
; HTC Magic
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01
;
;Moto Sholes
%SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_D00D
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0002
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0002&MI_01
%SingleAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB
%CompositeAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB&MI_01
[Google.NTamd64]
; HTC Dream
@@ -40,6 +47,13 @@ HKR,,Icon,,-1
%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0FFF
; HTC Magic
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01
;
;Moto Sholes
%SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_D00D
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0002
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0002&MI_01
%SingleAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB
%CompositeAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB&MI_01
[USB_Install]
Include = winusb.inf

View File

@@ -9,8 +9,6 @@
<classpathentry kind="src" path="packages/apps/Email/src"/>
<classpathentry kind="src" path="packages/apps/GoogleSearch/src"/>
<classpathentry kind="src" path="packages/apps/HTMLViewer/src"/>
<classpathentry kind="src" path="packages/apps/IM/src"/>
<classpathentry kind="src" path="packages/apps/IM/plugin"/>
<classpathentry kind="src" path="packages/apps/Launcher/src"/>
<classpathentry kind="src" path="packages/apps/Music/src"/>
<classpathentry kind="src" path="packages/apps/Mms/src"/>
@@ -47,6 +45,7 @@
<classpathentry kind="src" path="frameworks/base/telephony/java"/>
<classpathentry kind="src" path="frameworks/base/test-runner"/>
<classpathentry kind="src" path="frameworks/base/tts/java"/>
<classpathentry kind="src" path="frameworks/base/vpn/java"/>
<classpathentry kind="src" path="frameworks/base/wifi/java"/>
<classpathentry kind="src" path="frameworks/base/vpn/java"/>
<classpathentry kind="src" path="frameworks/policies/base/phone"/>
@@ -93,17 +92,15 @@
<classpathentry kind="src" path="dalvik/libcore/x-net/src/main/java"/>
<classpathentry kind="src" path="dalvik/libcore/xml/src/main/java"/>
<classpathentry kind="src" path="out/target/common/obj/APPS/ApiDemos_intermediates/src/src"/>
<classpathentry kind="src" path="out/target/common/obj/APPS/Browser_intermediates/src/src"/>
<classpathentry kind="src" path="out/target/common/obj/APPS/IM_intermediates/src/src"/>
<classpathentry kind="src" path="out/target/common/obj/APPS/Email_intermediates/src/src"/>
<classpathentry kind="src" path="out/target/common/obj/APPS/Music_intermediates/src/src"/>
<classpathentry kind="src" path="out/target/common/obj/APPS/Phone_intermediates/src/src"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/com.android.im.plugin_intermediates/src"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/im/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/location/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/tts/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/vpn/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/wifi/java"/>
<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/vpn/java"/>
<classpathentry kind="src" path="out/target/common/R"/>
@@ -114,6 +111,6 @@
<classpathentry kind="lib" path="external/googleclient/googleclient-lib.jar"/>
<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/google-framework_intermediates/javalib.jar"/>
<classpathentry kind="lib" path="out/target/common/obj/JAVA_LIBRARIES/googlelogin-client_intermediates/javalib.jar"/>
<classpathentry kind="lib" path="packages/apps/Calculator/arity-1.3.1.jar"/>
<classpathentry kind="lib" path="packages/apps/Calculator/arity-1.3.3.jar"/>
<classpathentry kind="output" path="out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/classes"/>
</classpath>

View File

@@ -91,7 +91,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>

View File

@@ -0,0 +1,3 @@
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := libgl2jni

View File

@@ -0,0 +1,10 @@
LOCAL_PATH:= $(LOCAL_PATH)/jni
include $(CLEAR_VARS)
LOCAL_MODULE := libgl2jni
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := gl_code.cpp
LOCAL_LDLIBS := -llog -lGLESv2
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 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.gl2jni">
<application
android:label="@string/gl2jni_activity">
<activity android:name="GL2JNIActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:launchMode="singleTask"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="5"/>
</manifest>

View File

@@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-4
target=android-5

View File

@@ -0,0 +1,24 @@
# 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_MODULE := libgl2jni
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := gl_code.cpp
LOCAL_LDLIBS := -llog -lGLESv2
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,182 @@
/*
* 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.
*/
// OpenGL ES 2.0 code
#include <jni.h>
#include <android/log.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LOG_TAG "libgl2jni"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
static void printGLString(const char *name, GLenum s) {
const char *v = (const char *) glGetString(s);
LOGI("GL %s = %s\n", name, v);
}
static void checkGlError(const char* op) {
for (GLint error = glGetError(); error; error
= glGetError()) {
LOGI("after %s() glError (0x%x)\n", op, error);
}
}
static const char gVertexShader[] = "attribute vec4 vPosition;\n"
"void main() {\n"
" gl_Position = vPosition;\n"
"}\n";
static const char gFragmentShader[] = "precision mediump float;\n"
"void main() {\n"
" gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
"}\n";
GLuint loadShader(GLenum shaderType, const char* pSource) {
GLuint shader = glCreateShader(shaderType);
if (shader) {
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen) {
char* buf = (char*) malloc(infoLen);
if (buf) {
glGetShaderInfoLog(shader, infoLen, NULL, buf);
LOGE("Could not compile shader %d:\n%s\n",
shaderType, buf);
free(buf);
}
glDeleteShader(shader);
shader = 0;
}
}
}
return shader;
}
GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
if (!vertexShader) {
return 0;
}
GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
if (!pixelShader) {
return 0;
}
GLuint program = glCreateProgram();
if (program) {
glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE) {
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength) {
char* buf = (char*) malloc(bufLength);
if (buf) {
glGetProgramInfoLog(program, bufLength, NULL, buf);
LOGE("Could not link program:\n%s\n", buf);
free(buf);
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
GLuint gProgram;
GLuint gvPositionHandle;
bool setupGraphics(int w, int h) {
printGLString("Version", GL_VERSION);
printGLString("Vendor", GL_VENDOR);
printGLString("Renderer", GL_RENDERER);
printGLString("Extensions", GL_EXTENSIONS);
LOGI("setupGraphics(%d, %d)", w, h);
gProgram = createProgram(gVertexShader, gFragmentShader);
if (!gProgram) {
LOGE("Could not create program.");
return false;
}
gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
checkGlError("glGetAttribLocation");
LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
gvPositionHandle);
glViewport(0, 0, w, h);
checkGlError("glViewport");
return true;
}
const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
0.5f, -0.5f };
void renderFrame() {
static float grey;
grey += 0.01f;
if (grey > 1.0f) {
grey = 0.0f;
}
glClearColor(grey, grey, grey, 1.0f);
checkGlError("glClearColor");
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
checkGlError("glClear");
glUseProgram(gProgram);
checkGlError("glUseProgram");
glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(gvPositionHandle);
checkGlError("glEnableVertexAttribArray");
glDrawArrays(GL_TRIANGLES, 0, 3);
checkGlError("glDrawArrays");
}
extern "C" {
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
};
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height)
{
setupGraphics(width, height);
}
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)
{
renderFrame();
}

Some files were not shown because too many files have changed in this diff Show More