diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 79d30fe428c6dae46ae66afeb9d5c5f6ae34ddeb (patch) | |
tree | 0abab02c285ed313457cdf4eb99adf9d758d6724 | |
download | Sync-79d30fe428c6dae46ae66afeb9d5c5f6ae34ddeb.tar.gz |
Initial Contributionandroid-1.0release-1.0cdma-import
-rw-r--r-- | Android.mk | 10 | ||||
-rw-r--r-- | AndroidManifest.xml | 22 | ||||
-rw-r--r-- | MODULE_LICENSE_APACHE2 | 0 | ||||
-rw-r--r-- | res/drawable/app_icon.png | bin | 0 -> 4001 bytes | |||
-rw-r--r-- | res/layout/sync_event.xml | 32 | ||||
-rw-r--r-- | res/layout/sync_history_screen.xml | 12 | ||||
-rw-r--r-- | res/layout/sync_panel.xml | 46 | ||||
-rw-r--r-- | res/layout/sync_screen.xml | 101 | ||||
-rw-r--r-- | res/values-de-rDE/strings.xml | 10 | ||||
-rw-r--r-- | res/values-en-rGB/strings.xml | 10 | ||||
-rw-r--r-- | res/values-es-rUS/strings.xml | 10 | ||||
-rw-r--r-- | res/values-fr-rFR/strings.xml | 10 | ||||
-rw-r--r-- | res/values-it-rIT/strings.xml | 10 | ||||
-rw-r--r-- | res/values-zh-rTW/strings.xml | 10 | ||||
-rw-r--r-- | res/values/strings.xml | 30 | ||||
-rw-r--r-- | res/values/styles.xml | 103 | ||||
-rw-r--r-- | src/com/android/sync/Sync.java | 375 | ||||
-rw-r--r-- | src/com/android/sync/SyncHistory.java | 92 |
18 files changed, 883 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..a9bd2e0 --- /dev/null +++ b/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := user eng + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := Sync + +include $(BUILD_PACKAGE) diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100644 index 0000000..50619ac --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,22 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.sync"> + + <application android:label="Sync" + android:icon="@drawable/app_icon"> + + <activity android:name="Sync" android:label="Sync (Old)"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.TEST" /> + </intent-filter> + </activity> + + <activity android:name="SyncHistory" android:label="SyncHistory"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + </intent-filter> + </activity> + + </application> + +</manifest> diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/MODULE_LICENSE_APACHE2 diff --git a/res/drawable/app_icon.png b/res/drawable/app_icon.png Binary files differnew file mode 100644 index 0000000..13d8cdd --- /dev/null +++ b/res/drawable/app_icon.png diff --git a/res/layout/sync_event.xml b/res/layout/sync_event.xml new file mode 100644 index 0000000..667c19c --- /dev/null +++ b/res/layout/sync_event.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="wrap_content" + android:layout_height="20dip"> + + <TextView android:id="@+id/time" + android:layout_width="105dip" + android:layout_height="20dip"/> + + <TextView android:id="@+id/authority" + android:layout_width="60dip" + android:layout_height="20dip"/> + + <TextView android:id="@+id/event" + android:layout_width="45dip" + android:layout_height="20dip"/> + + <TextView android:id="@+id/source" + android:layout_width="55dip" + android:layout_height="20dip"/> + + <TextView android:id="@+id/mesg" + android:layout_width="130dip" + android:layout_height="20dip"/> + + <TextView android:id="@+id/account" + android:layout_width="130dip" + android:layout_height="20dip"/> + +</LinearLayout> diff --git a/res/layout/sync_history_screen.xml b/res/layout/sync_history_screen.xml new file mode 100644 index 0000000..2c01a85 --- /dev/null +++ b/res/layout/sync_history_screen.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <ListView android:id="@+id/events" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + +</LinearLayout> + diff --git a/res/layout/sync_panel.xml b/res/layout/sync_panel.xml new file mode 100644 index 0000000..60b2f44 --- /dev/null +++ b/res/layout/sync_panel.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/layout/sync_notification.xml +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:paddingLeft="25dip" + android:paddingTop="17dip" + android:paddingRight="25dip" + android:paddingBottom="20dip" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content" > + + <TextView + android:id="@+id/status" + android:textSize="15sp" + android:textColor="#ffffffff" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/more_status" + android:textSize="15sp" + android:textColor="#ffffffff" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + +</LinearLayout> + + diff --git a/res/layout/sync_screen.xml b/res/layout/sync_screen.xml new file mode 100644 index 0000000..c101750 --- /dev/null +++ b/res/layout/sync_screen.xml @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/Preferences/assets/res/any/layout/sync_screen.xml +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:padding="10dip" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <TextView android:id="@+id/account" + style="@style/info_value" + android:maxLines="1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/sync_screen_account_text" /> + + <CheckBox android:id="@+id/listenForTickles" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/sync_screen_listenForTickles_text" /> + + <LinearLayout + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + + <TextView + style="@style/info_label" + android:maxLines="1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/sync_status_label" /> + + <TextView android:id="@+id/status" + style="@style/info_value" + android:maxLines="3" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/sync_screen_status_text" /> + </LinearLayout> + + <TextView android:id="@+id/moreStatus" + sytle="@style/info_value" + android:maxLines="3" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/sync_screen_moreStatus_text" /> + + <Spinner android:id="@+id/contentName" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + <requestFocus/> + </Spinner> + + <Button android:id="@+id/sync" + android:layout_marginTop="8dip" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/sync_screen_sync_text" /> + + <CheckBox android:id="@+id/syncProviderOnTickle" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + + <Button android:id="@+id/advanced" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/sync_screen_advanced_text"/> + + <LinearLayout android:id="@+id/advancedSection" + android:layout_marginTop="8dip" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="wrap_content"> + <Button android:id="@+id/history" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/sync_screen_history_text"/> + </LinearLayout> + +</LinearLayout> +</ScrollView> diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml new file mode 100644 index 0000000..c7df411 --- /dev/null +++ b/res/values-de-rDE/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="sync_screen_advanced_text">Erweitert</string> + <string name="sync_screen_history_text">Verlauf</string> + <string name="sync_screen_listenForTickles_text">Synchronisierung wechselt automatisch</string> + <string name="sync_screen_status_text">Leerlauf</string> + <string name="sync_screen_sync_text">Jetzt synchronisieren</string> + <string name="sync_status_label">Status:</string> +</resources> diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml new file mode 100644 index 0000000..1ee963a --- /dev/null +++ b/res/values-en-rGB/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="sync_screen_advanced_text">Advanced</string> + <string name="sync_screen_history_text">History</string> + <string name="sync_screen_listenForTickles_text">Sync changes automatically</string> + <string name="sync_screen_status_text">Idle</string> + <string name="sync_screen_sync_text">Sync now</string> + <string name="sync_status_label">Status:</string> +</resources> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml new file mode 100644 index 0000000..9da3111 --- /dev/null +++ b/res/values-es-rUS/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="sync_screen_advanced_text">Avanzado</string> + <string name="sync_screen_history_text">Historial</string> + <string name="sync_screen_listenForTickles_text">Cambio automático de sincronización</string> + <string name="sync_screen_status_text">Inactivo</string> + <string name="sync_screen_sync_text">Sincronizar ahora</string> + <string name="sync_status_label">Estado:</string> +</resources> diff --git a/res/values-fr-rFR/strings.xml b/res/values-fr-rFR/strings.xml new file mode 100644 index 0000000..9b45455 --- /dev/null +++ b/res/values-fr-rFR/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="sync_screen_advanced_text">Avancés</string> + <string name="sync_screen_history_text">Historique</string> + <string name="sync_screen_listenForTickles_text">La synchronisation change automatiquement</string> + <string name="sync_screen_status_text">Inactif</string> + <string name="sync_screen_sync_text">Synchroniser maintenant</string> + <string name="sync_status_label">État :</string> +</resources> diff --git a/res/values-it-rIT/strings.xml b/res/values-it-rIT/strings.xml new file mode 100644 index 0000000..8233413 --- /dev/null +++ b/res/values-it-rIT/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="sync_screen_advanced_text">Avanzate</string> + <string name="sync_screen_history_text">Cronologia</string> + <string name="sync_screen_listenForTickles_text">Cambia automaticamente sincronizzazione</string> + <string name="sync_screen_status_text">Inattivo</string> + <string name="sync_screen_sync_text">Sincronizza ora</string> + <string name="sync_status_label">Stato:</string> +</resources> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml new file mode 100644 index 0000000..aef6923 --- /dev/null +++ b/res/values-zh-rTW/strings.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="sync_screen_advanced_text">進階</string> + <string name="sync_screen_history_text">記錄</string> + <string name="sync_screen_listenForTickles_text">自動同步變更</string> + <string name="sync_screen_status_text">閒置</string> + <string name="sync_screen_sync_text">立即同步</string> + <string name="sync_status_label">狀態:</string> +</resources> diff --git a/res/values/strings.xml b/res/values/strings.xml new file mode 100644 index 0000000..a936213 --- /dev/null +++ b/res/values/strings.xml @@ -0,0 +1,30 @@ +<?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. +--> + +<resources> + + <string name="sync_status_label">Status:</string> + <string name="sync_screen_account_text"></string> + <string name="sync_screen_moreStatus_text"></string> + <string name="sync_screen_sync_text">Sync now</string> + <string name="sync_screen_advanced_text">Advanced</string> + <string name="sync_screen_history_text">History</string> + <string name="sync_screen_listenForTickles_text">Sync changes automatically</string> + <string name="sync_screen_status_text">Idle</string> + +</resources> + + diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 0000000..ae58671 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> +<!-- TODO: Remove, and move Settings styles into common --> +<resources> + + <style name="info_label"> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_width">wrap_content</item> + <item name="android:textAppearance">@style/TextAppearance.info_label</item> + <item name="android:paddingRight">4dip</item> + </style> + + <style name="info_value"> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_width">wrap_content</item> + <item name="android:textAppearance">@style/TextAppearance.info_value</item> + </style> + + <style name="info_small"> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_width">wrap_content</item> + <item name="android:textAppearance">@style/TextAppearance.info_small</item> + </style> + + <style name="info_layout"> + <item name="android:orientation">vertical</item> + <item name="android:paddingLeft">10dip</item> + <item name="android:paddingTop">10dip</item> + <item name="android:paddingRight">10dip</item> + <item name="android:paddingBottom">10dip</item> + <item name="android:layout_width">fill_parent</item> + <item name="android:layout_height">fill_parent</item> + </style> + + <style name="entry_layout"> + <item name="android:orientation">horizontal</item> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + </style> + + <style name="form_label"> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_width">fill_parent</item> + <item name="android:textAppearance">@style/TextAppearance.form_label</item> + </style> + + <style name="form_value"> + <item name="android:layout_height">wrap_content</item> + <item name="android:layout_width">fill_parent</item> + </style> + + <style name="form_layout"> + <item name="android:orientation">vertical</item> + <item name="android:paddingLeft">10dip</item> + <item name="android:paddingTop">0dip</item> + <item name="android:paddingRight">10dip</item> + <item name="android:paddingBottom">0dip</item> + <item name="android:layout_width">fill_parent</item> + <item name="android:layout_height">fill_parent</item> + </style> + + + + <style name="TextAppearance" parent="android:TextAppearance"> + </style> + + <style name="TextAppearance.info_label"> + <item name="android:textSize">14sp</item> + <item name="android:textStyle">bold</item> + </style> + + <style name="TextAppearance.form_label"> + <item name="android:textStyle">bold</item> + </style> + + <style name="TextAppearance.info_small"> + <item name="android:textSize">12sp</item> + <item name="android:textStyle">normal</item> + </style> + + <style name="TextAppearance.info_value"> + <item name="android:textSize">14sp</item> + <item name="android:textStyle">normal</item> + </style> + +</resources> diff --git a/src/com/android/sync/Sync.java b/src/com/android/sync/Sync.java new file mode 100644 index 0000000..425cce5 --- /dev/null +++ b/src/com/android/sync/Sync.java @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.sync; + +import android.app.Activity; +import android.app.ActivityThread; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.RemoteException; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Adapter; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.LinearLayout; +import android.widget.Spinner; +import android.widget.TextView; +import android.database.Cursor; +import android.database.DatabaseUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Observable; +import java.util.Observer; + +public class Sync extends Activity { + private static final String TAG = "SyncPanel"; + // TODO: move this to a centralized place? + private static final String SYNC_CONNECTION_SETTING_CHANGED + = "com.android.sync.SYNC_CONN_STATUS_CHANGED"; + + private static final int SYNC_BUTTON = 1; + private static final int CANCEL_BUTTON = 2; + + private Button mSyncButton; + private Button mAdvancedButton; + private LinearLayout mAdvancedSection; + private Button mHistoryButton; + private TextView mAccountTextView; + private TextView mStatusView; + private TextView mMoreStatusView; + + private CheckBox mListenForTicklesCheckBox; + private Spinner mContentNameSpinner; + private CheckBox mSyncProviderOnTickleCheckBox; + + private List mProviderNames; + private List mProviderInfos; + + private HashMap<String, Boolean> mProvidersToTickle = null; + + android.provider.Sync.Settings.QueryMap mSyncSettings; + + private OnClickListener mStartSync = new OnClickListener() { + public void onClick(View v) { + doSync(); + } + }; + + private OnClickListener mCancelSync = new OnClickListener() { + public void onClick(View v) { + mStatusView.setText("Cancelled"); + setSyncButton(SYNC_BUTTON); + getContentResolver().cancelSync(null /* cancel any sync */); + } + }; + + private OnClickListener mToggleListenForTickles = new OnClickListener() { + + public void onClick(View v) { + boolean oldListenForTickles = mSyncSettings.getListenForNetworkTickles(); + boolean listenForTickles = mListenForTicklesCheckBox.isChecked(); + if (oldListenForTickles != listenForTickles) { + mSyncSettings.setListenForNetworkTickles(listenForTickles); + Intent intent = new Intent(); + intent.setAction(SYNC_CONNECTION_SETTING_CHANGED); + sendBroadcast(intent); + } + } + }; + + private AdapterView.OnItemSelectedListener mContentNameListener = + new AdapterView.OnItemSelectedListener() { + public void onItemSelected( + AdapterView parent, View v, + int position, + long id) { + updateProviderUi(); + } + + public void onNothingSelected(AdapterView parent) { + // TODO: when does this happen? What does it mean? + } + }; + + private OnClickListener mToggleSyncOnTickle = new OnClickListener() { + public void onClick(View v) { + String providerName = getSelectedProviderName(); + boolean syncOnTickle = + mSyncProviderOnTickleCheckBox.isChecked(); + ContentResolver cr = getContentResolver(); + boolean oldShouldSyncOnTickle = + mSyncSettings.getSyncProviderAutomatically(providerName); + if (syncOnTickle != oldShouldSyncOnTickle) { + mSyncSettings.setSyncProviderAutomatically(providerName, syncOnTickle); + updateCachedSettingsAndProviderUi(); + } + } + }; + + private android.provider.Sync.Active.QueryMap mActiveSyncQueryMap; + + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + Intent intent = getIntent(); + + // init views + setContentView(R.layout.sync_screen); + + mAccountTextView = (TextView) findViewById(R.id.account); + mStatusView = (TextView) findViewById(R.id.status); + mMoreStatusView = (TextView) findViewById(R.id.moreStatus); + mSyncButton = (Button) findViewById(R.id.sync); + mAdvancedButton = (Button) findViewById(R.id.advanced); + mAdvancedSection = (LinearLayout) findViewById(R.id.advancedSection); + mAdvancedSection.setVisibility(View.INVISIBLE); + mAdvancedButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + int visibility = mAdvancedSection.getVisibility(); + mAdvancedSection.setVisibility(visibility == View.INVISIBLE ? + View.VISIBLE : View.INVISIBLE); + }}); + mHistoryButton = (Button) mAdvancedSection.findViewById(R.id.history); + mHistoryButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_RUN); + intent.setClass(Sync.this, SyncHistory.class); + intent.putExtra("authority", getSelectedProviderName()); + startActivity(intent); + }}); + + final ContentResolver contentResolver = getContentResolver(); + + mSyncSettings = new android.provider.Sync.Settings.QueryMap(contentResolver, + true /* keep updated */, null); + mSyncSettings.addObserver(new Observer() { + public void update(Observable o, Object arg) { + updateCachedSettingsAndProviderUi(); + } + }); + + mActiveSyncQueryMap = new android.provider.Sync.Active.QueryMap(getContentResolver(), + false /* don't keep updated, we will change this in onResume()/onPause() */, + null /* use this thread's handler for notifications */); + mActiveSyncQueryMap.addObserver(mSyncObserver); + + mProviderNames = new ArrayList(); + mProviderInfos = new ArrayList(); + try { + ActivityThread.getPackageManager().querySyncProviders(mProviderNames, + mProviderInfos); + } catch (RemoteException e) { + } + mProviderNames.add(0, "All"); + mProviderInfos.add(0, null); + + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_spinner_item, mProviderNames); + adapter.setDropDownViewResource( + android.R.layout.simple_dropdown_item_1line); + mContentNameSpinner = (Spinner) findViewById(R.id.contentName); + mContentNameSpinner.setAdapter(adapter); + mContentNameSpinner.setOnItemSelectedListener(mContentNameListener); + + mListenForTicklesCheckBox = + (CheckBox) findViewById(R.id.listenForTickles); + mListenForTicklesCheckBox.setOnClickListener(mToggleListenForTickles); + + mSyncProviderOnTickleCheckBox = + (CheckBox) findViewById(R.id.syncProviderOnTickle); + mSyncProviderOnTickleCheckBox.setOnClickListener( + mToggleSyncOnTickle); + + updateCachedSettingsAndProviderUi(); + updateStatusUi(); + } + + @Override + protected void onResume() { + super.onResume(); + mActiveSyncQueryMap.setKeepUpdated(true); + } + + @Override + protected void onPause() { + super.onPause(); + mActiveSyncQueryMap.setKeepUpdated(false); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mActiveSyncQueryMap != null) { + mActiveSyncQueryMap.close(); + mActiveSyncQueryMap = null; + } + } + + private void setSyncButton(int state) { + if (state == CANCEL_BUTTON) { + mSyncButton.setOnClickListener(mCancelSync); + mSyncButton.setText("Cancel"); + } else { + mSyncButton.setOnClickListener(mStartSync); + mSyncButton.setText("Sync"); + } + } + + private void doSync() { + mStatusView.setText("Syncing"); + setSyncButton(CANCEL_BUTTON); + + Uri filter = null; + String providerName = getSelectedProviderName(); + if (providerName != null) { + filter = Uri.parse("content://" + providerName); + } + + Bundle extras = new Bundle(); + extras.putBoolean(ContentResolver.SYNC_EXTRAS_FORCE, true); + getContentResolver().startSync(filter, extras); + } + + /** + * Returns the name of the selected provider, or null if "all" is selected. + * + * @return the name of the selected provider, or null if "all" is selected + */ + private String getSelectedProviderName() { + int selectedIndex = mContentNameSpinner.getSelectedItemPosition(); + if (selectedIndex != 0) { + return (String) mProviderNames.get(selectedIndex); + } else { + return null; + } + } + + private Observer mSyncObserver = new Observer() { + public void update(Observable o, Object arg) { + updateStatusUi(); + } + }; + + private int mProgressCount = 0; + + private String nextProgressText() { + int progressCount = mProgressCount; + mProgressCount++; + switch (progressCount) { + case 0: return "|"; + case 1: return "/"; + case 2: return "-"; + default: + mProgressCount = 0; + return "\\"; + } + } + + private void updateStatusUi() { + ContentValues syncInfo = mActiveSyncQueryMap.getActiveSyncInfo(); + boolean syncing = syncInfo != null; + + if (!syncing) { + + ContentValues values = queryPreviousSyncInfo(); + if (values == null) { + mAccountTextView.setVisibility(View.INVISIBLE); + mStatusView.setText("The sync history is empty"); + mMoreStatusView.setText(""); + } else { + mAccountTextView.setVisibility(View.VISIBLE); + String account = values.getAsString(android.provider.Sync.History.ACCOUNT); + String authority = values.getAsString(android.provider.Sync.History.AUTHORITY); + long elapsedTime = values.getAsLong(android.provider.Sync.History.ELAPSED_TIME); + String result = android.provider.Sync.History.mesgToString( + values.getAsString(android.provider.Sync.History.MESG)); + mAccountTextView.setText("Account: " + account); + mStatusView.setText("spent " + (elapsedTime / 1000) + " second(s) on " + + authority); + mMoreStatusView.setText("result: " + result); + } + } else { + String account = syncInfo.getAsString(android.provider.Sync.Active.ACCOUNT); + String authority = syncInfo.getAsString(android.provider.Sync.Active.AUTHORITY); + mAccountTextView.setVisibility(View.VISIBLE); + mAccountTextView.setText("Account: " + account); + mStatusView.setText("Syncing " + authority); + mMoreStatusView.setText(nextProgressText()); + } + + + if (syncing) { + setSyncButton(CANCEL_BUTTON); + } else { + setSyncButton(SYNC_BUTTON); + } + } + + private synchronized void updateProviderUi() { + String providerName = getSelectedProviderName(); + if (providerName != null) { + boolean syncOnTickle = mProvidersToTickle.get(providerName); + String text = "Sync " + providerName + + " when changes happen on the server"; + mSyncProviderOnTickleCheckBox.setChecked(syncOnTickle); + mSyncProviderOnTickleCheckBox.setText(text); + mSyncProviderOnTickleCheckBox.setVisibility(View.VISIBLE); + } else { + mSyncProviderOnTickleCheckBox.setVisibility(View.INVISIBLE); + } + } + + private synchronized void updateCachedSettingsAndProviderUi() { + if (mProvidersToTickle == null) { + mProvidersToTickle = new HashMap<String, Boolean>(); + Adapter adapter = mContentNameSpinner.getAdapter(); + int numProviders = adapter.getCount(); + for (int i = 0; i < numProviders; i++) { + mProvidersToTickle.put((String) adapter.getItem(i), false); + } + } + for (String provider : mProvidersToTickle.keySet()) { + mProvidersToTickle.put(provider, mSyncSettings.getSyncProviderAutomatically(provider)); + } + mListenForTicklesCheckBox.setChecked(mSyncSettings.getListenForNetworkTickles()); + updateProviderUi(); + } + + private ContentValues queryPreviousSyncInfo() { + Cursor c = getContentResolver().query(android.provider.Sync.History.CONTENT_URI, null, + "event=" + android.provider.Sync.History.EVENT_STOP, null, + android.provider.Sync.History.EVENT_TIME + " desc"); + try { + if (c.moveToNext()) { + ContentValues values = new ContentValues(); + DatabaseUtils.cursorRowToContentValues(c, values); + return values; + } else { + return null; + } + } finally { + c.close(); + } + } +} diff --git a/src/com/android/sync/SyncHistory.java b/src/com/android/sync/SyncHistory.java new file mode 100644 index 0000000..16dba4b --- /dev/null +++ b/src/com/android/sync/SyncHistory.java @@ -0,0 +1,92 @@ +/* + * 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.sync; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.database.Cursor; +import android.pim.Time; +import android.provider.Sync; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.view.LayoutInflater; +import android.widget.CursorAdapter; +import android.widget.ListView; +import android.widget.TextView; +import android.os.Bundle; + +public class SyncHistory extends Activity { + + private static final class SyncHistoryAdapter extends CursorAdapter { + + private final LayoutInflater mInflater; + private final Time mTime = new Time(Time.getCurrentTimezone()); + + public SyncHistoryAdapter(Context context, Cursor cursor) { + super(context, cursor); + mInflater = (LayoutInflater) + context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(R.layout.sync_event, parent, false); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + setText(view, R.id.account, cursor.getString(1)); + setText(view, R.id.authority, cursor.getString(2)); + setText(view, R.id.event, Sync.History.EVENTS[cursor.getInt(3)]); + setText(view, R.id.source, Sync.History.SOURCES[cursor.getInt(4)]); + mTime.set(cursor.getLong(5)); + String prettyTime = mTime.format("%m/%d %H:%M:%S"); + setText(view, R.id.time, prettyTime); + setText(view, R.id.mesg, cursor.getString(6)); + } + + private static void setText(View view, int id, String text) { + if (TextUtils.isEmpty(text)) { + return; + } + TextView textView = (TextView) view.findViewById(id); + textView.setText(text); + } + } + + private final static String[] sHistoryProjection = + new String[] { Sync.History._ID, + Sync.History.ACCOUNT, Sync.History.AUTHORITY, + Sync.History.EVENT, Sync.History.SOURCE, + Sync.History.EVENT_TIME, Sync.History.MESG }; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + setContentView(R.layout.sync_history_screen); + ListView items = (ListView) findViewById(R.id.events); + Cursor cursor = getContentResolver().query(Sync.History.CONTENT_URI, + sHistoryProjection, + null /* selection */, + null /* selectionArgs */, + Sync.History.EVENT_TIME + " DESC"); + startManagingCursor(cursor); + items.setAdapter(new SyncHistoryAdapter(this /* context */, cursor)); + } +} |