eclair snapshot

This commit is contained in:
Jean-Baptiste Queru
2009-11-12 18:45:17 -08:00
parent 50992e805e
commit 2c8ead32c7
3250 changed files with 153970 additions and 72935 deletions

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/accounts_tester_remove_account"
android:title="@string/accounts_tester_remove_account" />
<item android:id="@+id/accounts_tester_get_auth_token"
android:title="@string/accounts_tester_get_auth_token" />
<item android:id="@+id/accounts_tester_invalidate_auth_token"
android:title="@string/accounts_tester_invalidate_auth_token" />
<item android:id="@+id/accounts_tester_update_credentials"
android:title="@string/accounts_tester_update_credentials" />
<item android:id="@+id/accounts_tester_confirm_credentials"
android:title="@string/accounts_tester_confirm_credentials" />
</menu>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ListView android:id="@+id/accounts_tester_authenticators_list"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/accounts_tester_account_types_spinner_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_select_account_type"/>
<Spinner android:id="@+id/accounts_tester_account_types_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/accounts_tester_get_accounts_by_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_get_accounts_by_type"/>
<Button
android:id="@+id/accounts_tester_get_all_accounts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_get_all_accounts"/>
<Button android:id="@+id/accounts_tester_add_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_add_account"/>
<Button android:id="@+id/accounts_tester_edit_properties"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_edit_properties"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/accounts_tester_desiredFeatures"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_desired_features_label"/>
<EditText android:id="@+id/accounts_tester_desired_features"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minEms="15"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/accounts_tester_desiredFeatures"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/accounts_tester_desired_authtokentype_label"/>
<EditText android:id="@+id/accounts_tester_desired_authtokentype"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minEms="15"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ListView android:id="@+id/accounts_tester_accounts_list"
android:layout_width="fill_parent" android:layout_height="fill_parent"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2008 Esmertec AG.
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingTop="1dip"
android:paddingBottom="1dip"
android:paddingLeft="9dip"
android:paddingRight="9dip">
<ImageView android:id="@+id/accounts_tester_authenticator_icon"
android:paddingRight="9dip"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/accounts_tester_authenticator_label"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_gravity="center_horizontal|center_vertical" />
</LinearLayout>

View File

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

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/accounts_tester_get_auth_token_dialog_message"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="@string/accounts_tester_enter_auth_token_type" />
<EditText android:id="@+id/accounts_tester_auth_token_type"
android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minWidth="250dip"
android:scrollHorizontally="true"
android:capitalize="none"
android:autoText="false"/>
</LinearLayout>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2009, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="vertical"
android:gravity="fill" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingRight="6dip"
android:paddingLeft="6dip"
android:gravity="center_vertical" >
<ImageView android:id="@+id/icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="@android:dimen/app_icon_size"
android:layout_marginLeft="5dip"
android:layout_marginRight="11dip"
android:layout_gravity="center_vertical"
android:scaleType="fitCenter"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_marginBottom="2dip" />
<TextView android:id="@+id/description"
android:layout_marginTop="-4dip"
android:layout_gravity="center_vertical|left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="4dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView android:id="@+id/sync_adapters_spinner_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22dip"
android:text="@string/sync_adapters_spinner_label"/>
<Spinner android:id="@+id/sync_adapters_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="52dip">
<Button
android:id="@+id/bind_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/bind_button"
android:onClick="initiateBind"
android:layout_weight="2"/>
<Button
android:id="@+id/unbind_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/unbind_button"
android:onClick="initiateUnbind"
android:layout_weight="2"/>
</LinearLayout>
<TextView android:id="@+id/bound_adapter_text_view"
android:layout_width="wrap_content"
android:textSize="20dip"
android:layout_height="wrap_content"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="52dip">
<Button
android:id="@+id/start_sync_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/start_sync_button"
android:onClick="startSyncSelected"
android:layout_weight="2"/>
<Button
android:id="@+id/cancel_sync_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="@string/cancel_sync_button"
android:onClick="cancelSync"
android:layout_weight="2"/>
</LinearLayout>
<TextView android:id="@+id/status_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2009, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="52dip"
android:ellipsize="marquee" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,374 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.development;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.Dialog;
import android.app.AlertDialog;
import android.content.res.TypedArray;
import android.content.pm.RegisteredServicesCache;
import android.content.pm.RegisteredServicesCacheListener;
import android.content.SyncAdapterType;
import android.content.ISyncAdapter;
import android.content.ISyncContext;
import android.content.ServiceConnection;
import android.content.ComponentName;
import android.content.SyncResult;
import android.content.Intent;
import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ListView;
import android.util.AttributeSet;
import android.provider.Settings;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.view.View;
import android.view.LayoutInflater;
import java.util.Collection;
public class SyncAdapterDriver extends Activity
implements RegisteredServicesCacheListener<SyncAdapterType>,
AdapterView.OnItemClickListener {
private Spinner mSyncAdapterSpinner;
private Button mBindButton;
private Button mUnbindButton;
private TextView mBoundAdapterTextView;
private Button mStartSyncButton;
private Button mCancelSyncButton;
private TextView mStatusTextView;
private Object[] mSyncAdapters;
private SyncAdaptersCache mSyncAdaptersCache;
private final Object mSyncAdaptersLock = new Object();
private static final int DIALOG_ID_PICK_ACCOUNT = 1;
private ListView mAccountPickerView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSyncAdaptersCache = new SyncAdaptersCache(this);
setContentView(R.layout.sync_adapter_driver);
mSyncAdapterSpinner = (Spinner) findViewById(R.id.sync_adapters_spinner);
mBindButton = (Button) findViewById(R.id.bind_button);
mUnbindButton = (Button) findViewById(R.id.unbind_button);
mBoundAdapterTextView = (TextView) findViewById(R.id.bound_adapter_text_view);
mStartSyncButton = (Button) findViewById(R.id.start_sync_button);
mCancelSyncButton = (Button) findViewById(R.id.cancel_sync_button);
mStatusTextView = (TextView) findViewById(R.id.status_text_view);
getSyncAdapters();
mSyncAdaptersCache.setListener(this, null /* Handler */);
}
protected void onDestroy() {
mSyncAdaptersCache.close();
super.onDestroy();
}
private void getSyncAdapters() {
Collection<RegisteredServicesCache.ServiceInfo<SyncAdapterType>> all =
mSyncAdaptersCache.getAllServices();
synchronized (mSyncAdaptersLock) {
mSyncAdapters = new Object[all.size()];
String[] names = new String[mSyncAdapters.length];
int i = 0;
for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> item : all) {
mSyncAdapters[i] = item;
names[i] = item.type.authority + " - " + item.type.accountType;
i++;
}
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this,
R.layout.sync_adapter_item, names);
mSyncAdapterSpinner.setAdapter(adapter);
}
}
void updateUi() {
boolean isBound;
boolean hasServiceConnection;
synchronized (mServiceConnectionLock) {
hasServiceConnection = mActiveServiceConnection != null;
isBound = hasServiceConnection && mActiveServiceConnection.mBoundSyncAdapter != null;
}
mStartSyncButton.setEnabled(isBound);
mCancelSyncButton.setEnabled(isBound);
mBindButton.setEnabled(!hasServiceConnection);
mUnbindButton.setEnabled(hasServiceConnection);
}
public void startSyncSelected(View view) {
synchronized (mServiceConnectionLock) {
ISyncAdapter syncAdapter = null;
if (mActiveServiceConnection != null) {
syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
}
if (syncAdapter != null) {
removeDialog(DIALOG_ID_PICK_ACCOUNT);
mAccountPickerView = (ListView) LayoutInflater.from(this).inflate(
R.layout.account_list_view, null);
mAccountPickerView.setOnItemClickListener(this);
Account accounts[] = AccountManager.get(this).getAccountsByType(
mActiveServiceConnection.mSyncAdapter.type.accountType);
String[] accountNames = new String[accounts.length];
for (int i = 0; i < accounts.length; i++) {
accountNames[i] = accounts[i].name;
}
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(SyncAdapterDriver.this,
android.R.layout.simple_list_item_1, accountNames);
mAccountPickerView.setAdapter(adapter);
showDialog(DIALOG_ID_PICK_ACCOUNT);
}
}
updateUi();
}
private void startSync(String accountName) {
synchronized (mServiceConnectionLock) {
ISyncAdapter syncAdapter = null;
if (mActiveServiceConnection != null) {
syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
}
if (syncAdapter != null) {
try {
mStatusTextView.setText(
getString(R.string.status_starting_sync_format, accountName));
Account account = new Account(accountName,
mActiveServiceConnection.mSyncAdapter.type.accountType);
syncAdapter.startSync(mActiveServiceConnection,
mActiveServiceConnection.mSyncAdapter.type.authority,
account, new Bundle());
} catch (RemoteException e) {
mStatusTextView.setText(
getString(R.string.status_remote_exception_while_starting_sync));
}
}
}
updateUi();
}
public void cancelSync(View view) {
synchronized (mServiceConnectionLock) {
ISyncAdapter syncAdapter = null;
if (mActiveServiceConnection != null) {
syncAdapter = mActiveServiceConnection.mBoundSyncAdapter;
}
if (syncAdapter != null) {
try {
mStatusTextView.setText(getString(R.string.status_canceled_sync));
syncAdapter.cancelSync(mActiveServiceConnection);
} catch (RemoteException e) {
mStatusTextView.setText(
getString(R.string.status_remote_exception_while_canceling_sync));
}
}
}
updateUi();
}
public void onServiceChanged(SyncAdapterType type, boolean removed) {
getSyncAdapters();
}
@Override
protected Dialog onCreateDialog(final int id) {
if (id == DIALOG_ID_PICK_ACCOUNT) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.select_account_to_sync);
builder.setInverseBackgroundForced(true);
builder.setView(mAccountPickerView);
return builder.create();
}
return super.onCreateDialog(id);
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView item = (TextView) view;
final String accountName = item.getText().toString();
dismissDialog(DIALOG_ID_PICK_ACCOUNT);
startSync(accountName);
}
private class MyServiceConnection extends ISyncContext.Stub implements ServiceConnection {
private volatile ISyncAdapter mBoundSyncAdapter;
final RegisteredServicesCache.ServiceInfo<SyncAdapterType> mSyncAdapter;
public MyServiceConnection(
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter) {
mSyncAdapter = syncAdapter;
}
public void onServiceConnected(ComponentName name, IBinder service) {
mBoundSyncAdapter = ISyncAdapter.Stub.asInterface(service);
final SyncAdapterType type = mActiveServiceConnection.mSyncAdapter.type;
mBoundAdapterTextView.setText(getString(R.string.binding_connected_format,
type.authority, type.accountType));
updateUi();
}
public void onServiceDisconnected(ComponentName name) {
mBoundAdapterTextView.setText(getString(R.string.binding_not_connected));
mBoundSyncAdapter = null;
updateUi();
}
public void sendHeartbeat() {
runOnUiThread(new Runnable() {
public void run() {
uiThreadSendHeartbeat();
}
});
}
public void uiThreadSendHeartbeat() {
mStatusTextView.setText(getString(R.string.status_received_heartbeat));
}
public void uiThreadOnFinished(SyncResult result) {
if (result.hasError()) {
mStatusTextView.setText(
getString(R.string.status_sync_failed_format, result.toString()));
} else {
mStatusTextView.setText(
getString(R.string.status_sync_succeeded_format, result.toString()));
}
}
public void onFinished(final SyncResult result) throws RemoteException {
runOnUiThread(new Runnable() {
public void run() {
uiThreadOnFinished(result);
}
});
}
}
final Object mServiceConnectionLock = new Object();
MyServiceConnection mActiveServiceConnection;
public void initiateBind(View view) {
synchronized (mServiceConnectionLock) {
if (mActiveServiceConnection != null) {
mStatusTextView.setText(getString(R.string.status_already_bound));
return;
}
RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter =
getSelectedSyncAdapter();
if (syncAdapter == null) {
mStatusTextView.setText(getString(R.string.status_sync_adapter_not_selected));
return;
}
mActiveServiceConnection = new MyServiceConnection(syncAdapter);
Intent intent = new Intent();
intent.setAction("android.content.SyncAdapter");
intent.setComponent(syncAdapter.componentName);
intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
com.android.internal.R.string.sync_binding_label);
intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
this, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0));
if (!bindService(intent, mActiveServiceConnection, Context.BIND_AUTO_CREATE)) {
mBoundAdapterTextView.setText(getString(R.string.binding_bind_failed));
mActiveServiceConnection = null;
return;
}
mBoundAdapterTextView.setText(getString(R.string.binding_waiting_for_connection));
}
updateUi();
}
public void initiateUnbind(View view) {
synchronized (mServiceConnectionLock) {
if (mActiveServiceConnection == null) {
return;
}
mBoundAdapterTextView.setText("");
unbindService(mActiveServiceConnection);
mActiveServiceConnection = null;
}
updateUi();
}
private RegisteredServicesCache.ServiceInfo<SyncAdapterType> getSelectedSyncAdapter() {
synchronized (mSyncAdaptersLock) {
final int position = mSyncAdapterSpinner.getSelectedItemPosition();
if (position == AdapterView.INVALID_POSITION) {
return null;
}
try {
//noinspection unchecked
return (RegisteredServicesCache.ServiceInfo<SyncAdapterType>)
mSyncAdapters[position];
} catch (Exception e) {
return null;
}
}
}
static class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> {
private static final String SERVICE_INTERFACE = "android.content.SyncAdapter";
private static final String SERVICE_META_DATA = "android.content.SyncAdapter";
private static final String ATTRIBUTES_NAME = "sync-adapter";
SyncAdaptersCache(Context context) {
super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, null);
}
public SyncAdapterType parseServiceAttributes(String packageName, AttributeSet attrs) {
TypedArray sa = mContext.getResources().obtainAttributes(attrs,
com.android.internal.R.styleable.SyncAdapter);
try {
final String authority =
sa.getString(com.android.internal.R.styleable.SyncAdapter_contentAuthority);
final String accountType =
sa.getString(com.android.internal.R.styleable.SyncAdapter_accountType);
if (authority == null || accountType == null) {
return null;
}
final boolean userVisible = sa.getBoolean(
com.android.internal.R.styleable.SyncAdapter_userVisible, true);
final boolean supportsUploading = sa.getBoolean(
com.android.internal.R.styleable.SyncAdapter_supportsUploading, true);
return new SyncAdapterType(authority, accountType, userVisible, supportsUploading);
} finally {
sa.recycle();
}
}
}
}