merge from eclair
13
apps/BluetoothDebug/Android.mk
Normal 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)
|
||||
38
apps/BluetoothDebug/AndroidManifest.xml
Normal 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
@@ -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
|
||||
|
||||
@@ -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
@@ -0,0 +1,5 @@
|
||||
.classpath
|
||||
.project
|
||||
bin
|
||||
default.properties
|
||||
gen
|
||||
BIN
apps/CustomLocale/res/drawable-hdpi/icon.png
Executable file
|
After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
BIN
apps/Development/res/drawable-hdpi/ic_launcher_devtools.png
Executable file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
apps/Development/res/drawable-hdpi/stat_sample.png
Executable file
|
After Width: | Height: | Size: 388 B |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
34
apps/Development/res/layout/account_list_context_menu.xml
Normal 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>
|
||||
20
apps/Development/res/layout/account_list_view.xml
Normal 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"/>
|
||||
117
apps/Development/res/layout/accounts_tester.xml
Normal 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>
|
||||
43
apps/Development/res/layout/authenticators_list_item.xml
Normal 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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
36
apps/Development/res/layout/get_auth_token_view.xml
Normal 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>
|
||||
68
apps/Development/res/layout/package_list_item.xml
Normal 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>
|
||||
86
apps/Development/res/layout/sync_adapter_driver.xml
Normal 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>
|
||||
26
apps/Development/res/layout/sync_adapter_item.xml
Normal 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" />
|
||||
@@ -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>
|
||||
|
||||
431
apps/Development/src/com/android/development/AccountsTester.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
mList = context.getPackageManager().getInstalledApplications(0);
|
||||
if (mList != null) {
|
||||
Collections.sort(mList, sDisplayNameComparator);
|
||||
mList.add(0, null);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
view = convertView;
|
||||
}
|
||||
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;
|
||||
|
||||
class MyApplicationInfo {
|
||||
ApplicationInfo info;
|
||||
String label;
|
||||
}
|
||||
|
||||
private final static Comparator sDisplayNameComparator = new Comparator() {
|
||||
public final int
|
||||
compare(Object a, Object b)
|
||||
{
|
||||
CharSequence sa = ((ApplicationInfo) a).packageName;
|
||||
CharSequence sb = ((ApplicationInfo) b).packageName;
|
||||
public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
|
||||
private List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
|
||||
|
||||
return collator.compare(sa, sb);
|
||||
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);
|
||||
}
|
||||
|
||||
@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 {
|
||||
icon.setImageDrawable(null);
|
||||
description.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final static Comparator<MyApplicationInfo> sDisplayNameComparator
|
||||
= new Comparator<MyApplicationInfo>() {
|
||||
public final int
|
||||
compare(MyApplicationInfo a, MyApplicationInfo b) {
|
||||
return collator.compare(a.label, b.label);
|
||||
}
|
||||
|
||||
private final Collator collator = Collator.getInstance();
|
||||
|
||||
@@ -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>(
|
||||
@@ -169,6 +174,7 @@ public class DevelopmentSettings extends Activity {
|
||||
updateFlingerOptions();
|
||||
updateSleepOptions();
|
||||
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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -319,15 +328,17 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
apps/GestureBuilder/res/drawable-hdpi/ic_gesturebuilder.png
Executable file
|
After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
10
apps/NinePatchLab/Android.mk
Normal 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)
|
||||
11
apps/NinePatchLab/AndroidManifest.xml
Normal 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
@@ -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
|
||||
|
||||
BIN
apps/NinePatchLab/res/drawable/bg_grad_blue.9.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
apps/NinePatchLab/res/drawable/bg_grad_green.9.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
apps/NinePatchLab/res/drawable/bg_grad_grey.9.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
apps/NinePatchLab/res/drawable/bg_grad_red.9.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
apps/NinePatchLab/res/drawable/bg_grad_yellow.9.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 855 B |
|
After Width: | Height: | Size: 860 B |
|
After Width: | Height: | Size: 761 B |
|
After Width: | Height: | Size: 761 B |
|
After Width: | Height: | Size: 1000 B |
|
After Width: | Height: | Size: 1000 B |
210
apps/NinePatchLab/src/com/android/ninepatch/NinePatchLab.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BIN
apps/SpareParts/res/drawable-hdpi/app_icon.png
Executable file
|
After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
BIN
apps/Term/res/drawable-hdpi/app_terminal.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
apps/Term/res/drawable-hdpi/atari_small.png
Executable file
|
After Width: | Height: | Size: 974 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1006 B After Width: | Height: | Size: 1006 B |
75
apps/Term/src/com/android/term/Exec.java
Normal 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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"/
|
||||
|
||||
|
||||
@@ -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: "
|
||||
|
||||
@@ -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(
|
||||
@@ -162,20 +172,11 @@ 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());
|
||||
@@ -185,9 +186,13 @@ public class MonkeySourceScript implements MonkeyEventSource {
|
||||
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
|
||||
@@ -213,9 +218,9 @@ public class MonkeySourceScript implements MonkeyEventSource {
|
||||
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);
|
||||
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
|
||||
@@ -225,6 +230,59 @@ public class MonkeySourceScript implements MonkeyEventSource {
|
||||
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() {
|
||||
@@ -253,10 +311,14 @@ 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;
|
||||
|
||||
@@ -270,14 +332,6 @@ public class MonkeySourceScript implements MonkeyEventSource {
|
||||
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 ||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -393,6 +393,9 @@ layouts {
|
||||
color 0xe0e0e0
|
||||
event EV_SW:0:0
|
||||
|
||||
dpad-rotation 3
|
||||
|
||||
|
||||
part1 {
|
||||
name portrait
|
||||
x 800
|
||||
|
||||
BIN
emulator/skins/WQVGA400/arrow_down.png
Normal file
|
After Width: | Height: | Size: 449 B |
BIN
emulator/skins/WQVGA400/arrow_left.png
Normal file
|
After Width: | Height: | Size: 825 B |
BIN
emulator/skins/WQVGA400/arrow_right.png
Normal file
|
After Width: | Height: | Size: 795 B |
BIN
emulator/skins/WQVGA400/arrow_up.png
Normal file
|
After Width: | Height: | Size: 453 B |
BIN
emulator/skins/WQVGA400/background_land.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
emulator/skins/WQVGA400/background_port.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
BIN
emulator/skins/WQVGA400/button.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
emulator/skins/WQVGA400/controls.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
2
emulator/skins/WQVGA400/hardware.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=120
|
||||
BIN
emulator/skins/WQVGA400/key.png
Normal file
|
After Width: | Height: | Size: 154 B |
BIN
emulator/skins/WQVGA400/keyboard.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
438
emulator/skins/WQVGA400/layout
Normal 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
|
||||
}
|
||||
BIN
emulator/skins/WQVGA400/select.png
Normal file
|
After Width: | Height: | Size: 384 B |
BIN
emulator/skins/WQVGA400/spacebar.png
Normal file
|
After Width: | Height: | Size: 192 B |
@@ -393,6 +393,8 @@ layouts {
|
||||
color 0xe0e0e0
|
||||
event EV_SW:0:0
|
||||
|
||||
dpad-rotation 3
|
||||
|
||||
part1 {
|
||||
name portrait
|
||||
x 800
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=240
|
||||
vm.heapSize=24
|
||||
|
||||
@@ -394,6 +394,8 @@ layouts {
|
||||
color 0xe0e0e0
|
||||
event EV_SW:0:0
|
||||
|
||||
dpad-rotation 3
|
||||
|
||||
part1 {
|
||||
name portrait
|
||||
x 900
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
# skin-specific hardware values
|
||||
hw.lcd.density=240
|
||||
vm.heapSize=24
|
||||
|
||||
@@ -394,6 +394,8 @@ layouts {
|
||||
color 0xe0e0e0
|
||||
event EV_SW:0:0
|
||||
|
||||
dpad-rotation 3
|
||||
|
||||
part1 {
|
||||
name portrait
|
||||
x 900
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
3
ndk/apps/hello-gl2/Application.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
APP_PROJECT_PATH := $(call my-dir)/project
|
||||
APP_MODULES := libgl2jni
|
||||
|
||||
10
ndk/apps/hello-gl2/project/Android.mk
Normal 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)
|
||||
36
ndk/apps/hello-gl2/project/AndroidManifest.xml
Normal 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>
|
||||
@@ -8,4 +8,4 @@
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-4
|
||||
target=android-5
|
||||
24
ndk/apps/hello-gl2/project/jni/Android.mk
Normal 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)
|
||||
182
ndk/apps/hello-gl2/project/jni/gl_code.cpp
Normal 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();
|
||||
}
|
||||