summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit79d30fe428c6dae46ae66afeb9d5c5f6ae34ddeb (patch)
tree0abab02c285ed313457cdf4eb99adf9d758d6724
downloadSync-79d30fe428c6dae46ae66afeb9d5c5f6ae34ddeb.tar.gz
-rw-r--r--Android.mk10
-rw-r--r--AndroidManifest.xml22
-rw-r--r--MODULE_LICENSE_APACHE20
-rw-r--r--res/drawable/app_icon.pngbin0 -> 4001 bytes
-rw-r--r--res/layout/sync_event.xml32
-rw-r--r--res/layout/sync_history_screen.xml12
-rw-r--r--res/layout/sync_panel.xml46
-rw-r--r--res/layout/sync_screen.xml101
-rw-r--r--res/values-de-rDE/strings.xml10
-rw-r--r--res/values-en-rGB/strings.xml10
-rw-r--r--res/values-es-rUS/strings.xml10
-rw-r--r--res/values-fr-rFR/strings.xml10
-rw-r--r--res/values-it-rIT/strings.xml10
-rw-r--r--res/values-zh-rTW/strings.xml10
-rw-r--r--res/values/strings.xml30
-rw-r--r--res/values/styles.xml103
-rw-r--r--src/com/android/sync/Sync.java375
-rw-r--r--src/com/android/sync/SyncHistory.java92
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
new file mode 100644
index 0000000..13d8cdd
--- /dev/null
+++ b/res/drawable/app_icon.png
Binary files differ
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));
+ }
+}