Merge "Added contentDescription to IME settings image button."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9712a63..4118f32 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -639,6 +639,11 @@
android:resource="@id/privacy_settings" />
</activity>
+ <activity android:name="SetFullBackupPassword"
+ android:theme="@android:style/Theme.Holo.DialogWhenLarge"
+ android:exported="false">
+ </activity>
+
<activity android:name="CredentialStorage"
android:theme="@style/Transparent"
android:configChanges="orientation|keyboardHidden|screenSize">
@@ -970,6 +975,19 @@
</intent-filter>
</activity>
+ <!-- NFC settings -->
+ <activity android:name="Settings$NfcSharingSettingsActivity"
+ android:label="@string/zeroclick_settings_title"
+ android:clearTaskOnLaunch="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.settings.NFCSHARING_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.nfc.ZeroClick" />
+ </activity>
+
<!-- Accessibility tutorial -->
<activity android:name="AccessibilityTutorialActivity"
android:label="@string/accessibility_tutorial_title"
diff --git a/res/layout/data_usage_chart.xml b/res/layout/data_usage_chart.xml
index a942bb3..3409d64 100644
--- a/res/layout/data_usage_chart.xml
+++ b/res/layout/data_usage_chart.xml
@@ -51,20 +51,6 @@
settings:fillColorSecondary="#0000" />
<com.android.settings.widget.ChartSweepView
- android:id="@+id/sweep_left"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- settings:sweepDrawable="@drawable/data_sweep_left"
- settings:followAxis="horizontal" />
-
- <com.android.settings.widget.ChartSweepView
- android:id="@+id/sweep_right"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- settings:sweepDrawable="@drawable/data_sweep_right"
- settings:followAxis="horizontal" />
-
- <com.android.settings.widget.ChartSweepView
android:id="@+id/sweep_warning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -84,4 +70,18 @@
settings:labelTemplate="@string/data_usage_sweep_limit"
settings:labelColor="#c01a2c" />
+ <com.android.settings.widget.ChartSweepView
+ android:id="@+id/sweep_left"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ settings:sweepDrawable="@drawable/data_sweep_left"
+ settings:followAxis="horizontal" />
+
+ <com.android.settings.widget.ChartSweepView
+ android:id="@+id/sweep_right"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ settings:sweepDrawable="@drawable/data_sweep_right"
+ settings:followAxis="horizontal" />
+
</com.android.settings.widget.DataUsageChartView>
diff --git a/res/layout/data_usage_cycles.xml b/res/layout/data_usage_cycles.xml
new file mode 100644
index 0000000..225fb4b
--- /dev/null
+++ b/res/layout/data_usage_cycles.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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:id="@+id/cycles"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/data_usage_cycle" />
+
+ <Spinner
+ android:id="@+id/cycles_spinner"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1" />
+
+</LinearLayout>
diff --git a/res/layout/data_usage_header.xml b/res/layout/data_usage_header.xml
index 547d85d..52f56c1 100644
--- a/res/layout/data_usage_header.xml
+++ b/res/layout/data_usage_header.xml
@@ -32,28 +32,19 @@
android:divider="?android:attr/listDivider" />
</FrameLayout>
- <LinearLayout
+ <include layout="@layout/data_usage_cycles" />
+ <include layout="@layout/data_usage_chart" />
+
+ <TextView
+ android:id="@+id/usage_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
android:paddingLeft="16dip"
- android:paddingRight="16dip">
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:text="@string/data_usage_cycle" />
-
- <Spinner
- android:id="@+id/cycles"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1" />
-
- </LinearLayout>
-
- <include layout="@layout/data_usage_chart" />
<include layout="@layout/data_usage_detail" />
</LinearLayout>
diff --git a/res/layout/data_usage_item.xml b/res/layout/data_usage_item.xml
index d709753..36f8b4d 100644
--- a/res/layout/data_usage_item.xml
+++ b/res/layout/data_usage_item.xml
@@ -17,20 +17,22 @@
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="8dip"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
android:columnCount="2">
- <!-- TODO: consider using canShrink -->
<TextView
android:id="@android:id/title"
+ android:layout_width="0dip"
+ android:layout_gravity="fill_horizontal"
android:singleLine="true"
android:ellipsize="marquee"
- android:layout_columnFlexibility="canStretch"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@android:id/summary"
- android:layout_gravity="right"
android:layout_marginLeft="8dip"
android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/res/layout/set_backup_pw.xml b/res/layout/set_backup_pw.xml
new file mode 100644
index 0000000..3743c81
--- /dev/null
+++ b/res/layout/set_backup_pw.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="16dip"
+ >
+
+ <TextView
+ android:id="@+id/prompt1"
+ android:text="@string/current_backup_pw_prompt"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
+
+ <EditText
+ android:id="@+id/current_backup_pw"
+ android:layout_below="@id/prompt1"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:singleLine="true"
+ android:password="true" />
+
+ <TextView
+ android:id="@+id/prompt2"
+ android:layout_below="@id/current_backup_pw"
+ android:text="@string/new_backup_pw_prompt"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
+
+ <EditText
+ android:id="@+id/new_backup_pw"
+ android:layout_below="@id/prompt2"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:singleLine="true"
+ android:password="true" />
+
+ <TextView
+ android:id="@+id/prompt3"
+ android:layout_below="@id/new_backup_pw"
+ android:text="@string/confirm_new_backup_pw_prompt"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
+
+ <EditText
+ android:id="@+id/confirm_new_backup_pw"
+ android:layout_below="@id/prompt3"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:singleLine="true"
+ android:password="true" />
+
+ <Button
+ android:id="@+id/backup_pw_cancel_button"
+ android:layout_below="@id/confirm_new_backup_pw"
+ android:text="@string/backup_pw_cancel_button_text"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
+
+ <Button
+ android:id="@+id/backup_pw_set_button"
+ android:layout_below="@id/confirm_new_backup_pw"
+ android:layout_toRightOf="@id/backup_pw_cancel_button"
+ android:text="@string/backup_pw_set_button_text"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
+
+</RelativeLayout>
diff --git a/res/layout/vpn_dialog.xml b/res/layout/vpn_dialog.xml
index ffbfd4d..b4779e6 100644
--- a/res/layout/vpn_dialog.xml
+++ b/res/layout/vpn_dialog.xml
@@ -15,7 +15,7 @@
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -96,15 +96,27 @@
android:prompt="@string/vpn_ipsec_ca_cert" />
</LinearLayout>
+ <CheckBox style="@style/vpn_value" android:id="@+id/show_options"
+ android:singleLine="false"
+ android:text="@string/vpn_show_options"/>
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/options"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:visibility="gone">
<TextView style="@style/vpn_label" android:text="@string/vpn_search_domains"/>
<EditText style="@style/vpn_value" android:id="@+id/search_domains"
android:hint="@string/vpn_not_used"/>
- <!-- Not sure if we have time to make it. -->
- <TextView style="@style/vpn_label" android:text="@string/vpn_routes"
- android:visibility="gone"/>
+ <TextView style="@style/vpn_label" android:text="@string/vpn_dns_servers"/>
+ <EditText style="@style/vpn_value" android:id="@+id/dns_servers"
+ android:hint="@string/vpn_not_used"/>
+
+ <TextView style="@style/vpn_label" android:text="@string/vpn_routes"/>
<EditText style="@style/vpn_value" android:id="@+id/routes"
- android:visibility="gone"/>
+ android:hint="@string/vpn_not_used"/>
</LinearLayout>
<LinearLayout android:id="@+id/login"
diff --git a/res/layout/zeroclick.xml b/res/layout/zeroclick.xml
index 99558f3..d039e89 100644
--- a/res/layout/zeroclick.xml
+++ b/res/layout/zeroclick.xml
@@ -30,28 +30,6 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <View
- android:paddingTop="53dip"
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="#ff404040"
- />
-
- <CheckBox android:id="@+id/zeroclick_checkbox"
- android:layout_width="match_parent"
- android:layout_height="64dip"
- android:gravity="center_vertical"
- android:text="@string/zeroclick_label"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorSecondary"
- />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="1dip"
- android:background="#ff404040"
- />
-
<TextView android:id="@+id/zeroclick_explained"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 05724ce..cf35ba8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1091,11 +1091,13 @@
<!-- Used in the 1st-level settings screen to turn on NFC -->
<string name="nfc_quick_toggle_title">NFC</string>
<!-- Used to enter the Zero-click sharing preferences screen -->
- <string name="zeroclick_settings_title">Zero-click sharing</string>
+ <string name="zeroclick_settings_title">Tap to share</string>
<string name="zeroclick_settings_summary"></string>
+ <string name="zeroclick_on_summary">On</string>
+ <string name="zeroclick_off_summary">Off</string>
<!-- Used in the zero-click sharing preferences screen -->
<string name="zeroclick_label">Zero-click sharing</string>
- <string name="zeroclick_explained">Zero-click sharing allows you to share content from applications, just by tapping your NFC-enabled device to another.</string>
+ <string name="zeroclick_explained">Tap to share allows you to share content from applications, just by tapping your NFC-enabled device to another.</string>
<!-- Wi-Fi Settings --> <skip />
<!-- Used in the 1st-level settings screen to turn on Wi-Fi -->
@@ -1781,12 +1783,12 @@
<string name="storage_menu_usb">USB transfer settings</string>
<!-- Storage setting. Title for USB transfer settings [CHAR LIMIT=30]-->
<string name="storage_title_usb">USB transfer settings</string>
+ <!-- Storage setting. USB connection category [CHAR LIMIT=30]-->
+ <string name="usb_connection_category">Connect as</string>
<!-- Storage setting. Label for MTP setting [CHAR LIMIT=30]-->
- <string name="usb_label_mtp">Connect as a media device (MTP)</string>
+ <string name="usb_label_mtp">Media device (MTP)</string>
<!-- Storage setting. Label for PTP setting [CHAR LIMIT=30]-->
- <string name="usb_label_ptp">Connect as a camera (PTP)</string>
- <!-- Storage setting. Label for installer CD [CHAR LIMIT=30]-->
- <string name="usb_label_installer_cd">Install Android File Transfer application for Mac</string>
+ <string name="usb_label_ptp">Camera (PTP)</string>
<!-- Storage setting. Label for installer CD [CHAR LIMIT=30]-->
<string name="usb_label_installer_cd_done">Done installing Android File Transfer application for Mac</string>
<!-- Installer CD dialog title [CHAR LIMIT=30] -->
@@ -3080,6 +3082,14 @@
<string name="auto_restore_title">Automatic restore</string>
<!-- Summary text of the "automatic restore" setting -->
<string name="auto_restore_summary">If I reinstall an application, restore backed up settings or other data</string>
+
+ <!-- Local backup password menu title [CHAR LIMIT=25] -->
+ <string name="local_backup_password_title">Local backup password</string>
+ <!-- Summary text of the "local backup password" setting when the user has not supplied a password -->
+ <string name="local_backup_password_summary_none">Local full backups are not currently protected.</string>
+ <!-- Summary text of the "local backup password" setting when the user has already supplied a password -->
+ <string name="local_backup_password_summary_change">Select to change or remove the password for local full backups</string>
+
<!-- Dialog title for confirmation to erase backup data from server -->
<string name="backup_erase_dialog_title">Backup</string>
<!-- Dialog title for confirmation to erase backup data from server -->
@@ -3470,6 +3480,8 @@
<string name="data_usage_uninstalled_apps">Removed apps</string>
<!-- Combination of total network bytes sent and received by an application. [CHAR LIMIT=NONE] -->
<string name="data_usage_received_sent"><xliff:g id="received" example="128KB">%1$s</xliff:g> received, <xliff:g id="sent" example="1.3GB">%2$s</xliff:g> sent</string>
+ <!-- Label displaying total network data transferred during a specific time period. [CHAR LIMIT=64] -->
+ <string name="data_usage_total_during_range">Data usage: <xliff:g id="total" example="128KB">%1$s</xliff:g> between <xliff:g id="range" example="Jul 1 - Jul 31">%2$s</xliff:g></string>
<!-- Button at the bottom of the CryptKeeper screen to make an emergency call. -->
<string name="cryptkeeper_emergency_call">Emergency call</string>
@@ -3494,18 +3506,21 @@
<string name="vpn_ipsec_user_cert">IPSec user certificate</string>
<!-- Selection label for the IPSec CA certificate of a VPN network. [CHAR LIMIT=40] -->
<string name="vpn_ipsec_ca_cert">IPSec CA certificate</string>
+ <!-- Checkbox label to show advanced options of a VPN network. [CHAR LIMIT=40] -->
+ <string name="vpn_show_options">Show advanced options</string>
<!-- Input label for the DNS search domains of a VPN network. [CHAR LIMIT=40] -->
<string name="vpn_search_domains">DNS search domains</string>
+ <!-- Input label for the DNS servers of a VPN network. [CHAR LIMIT=40] -->
+ <string name="vpn_dns_servers">DNS servers (e.g. 8.8.8.8)</string>
<!-- Input label for the forwarding routes of a VPN network. [CHAR LIMIT=40] -->
- <string name="vpn_routes">Forwarding routes</string>
+ <string name="vpn_routes">Forwarding routes (e.g. 10.0.0.0/8)</string>
<!-- Input label for the username of a VPN network. [CHAR LIMIT=40] -->
<string name="vpn_username">Username</string>
<!-- Input label for the password of a VPN network. [CHAR LIMIT=40] -->
<string name="vpn_password">Password</string>
<!-- Checkbox label to save the username and the password for a VPN network. [CHAR LIMIT=40] -->
<string name="vpn_save_login">Save account information</string>
-
- <!-- Hint for not filling an optional field in a VPN configuration. [CHAR LIMIT=40] -->
+ <!-- Hint for not using an optional feature of a VPN network. [CHAR LIMIT=40] -->
<string name="vpn_not_used">(not used)</string>
<!-- Option to not use a CA certificate to verify the VPN server. [CHAR LIMIT=40] -->
<string name="vpn_no_ca_cert">(do not verify server)</string>
@@ -3588,4 +3603,17 @@
<!-- Title for spelling correction settings -->
<string name="spellcheckers_settings_title">Spelling correction</string>
+
+ <!-- Prompt for the user to enter their current full-backup password -->
+ <string name="current_backup_pw_prompt">Enter your current full backup password here</string>
+ <!-- Prompt for the user to enter a new full-backup password -->
+ <string name="new_backup_pw_prompt">Enter a new password for full backups here</string>
+ <!-- Prompt for the user to confirm the new full-backup password by re-entering it -->
+ <string name="confirm_new_backup_pw_prompt">Please re-enter your new full backup password here</string>
+
+ <!-- Button label for setting the user's new full-backup password -->
+ <string name="backup_pw_set_button_text">Set backup password</string>
+ <!-- Button label for cancelling the new-password operation and retaining the user's previous full-backup password -->
+ <string name="backup_pw_cancel_button_text">Cancel</string>
+
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index ffa7912..32e0a48 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -143,15 +143,14 @@
<style name="vpn_label">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
- <item name="android:textSize">16sp</item>
+ <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
</style>
<style name="vpn_value">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
- <item name="android:textSize">18sp</item>
+ <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
<item name="android:singleLine">true</item>
- <item name="android:paddingBottom">1mm</item>
</style>
<style name="InputMethodPreferenceStyle">
diff --git a/res/xml/privacy_settings.xml b/res/xml/privacy_settings.xml
index 54d88f7..60efef6 100644
--- a/res/xml/privacy_settings.xml
+++ b/res/xml/privacy_settings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2009-2011 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.
@@ -38,6 +38,16 @@
android:title="@string/auto_restore_title"
android:summary="@string/auto_restore_summary"
android:persistent="false" />
+ <PreferenceScreen
+ android:key="local_backup_password"
+ android:title="@string/local_backup_password_title"
+ android:summary="@string/local_backup_password_summary_none"
+ android:persistent="false" >
+ <intent
+ android:action="android.settings.privacy.SET_FULL_BACKUP_PASSWORD"
+ android:targetPackage="com.android.settings"
+ android:targetClass="com.android.settings.SetFullBackupPassword" />
+ </PreferenceScreen>
</PreferenceCategory>
<PreferenceCategory
diff --git a/res/xml/usb_settings.xml b/res/xml/usb_settings.xml
index e2a950d..28ef99b 100644
--- a/res/xml/usb_settings.xml
+++ b/res/xml/usb_settings.xml
@@ -17,6 +17,9 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/location_settings_title">
+ <PreferenceCategory
+ android:title="@string/usb_connection_category" />
+
<CheckBoxPreference
android:key="usb_mtp"
android:title="@string/usb_label_mtp"
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index 0b5d295..d87080f 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -128,6 +128,7 @@
private static final boolean LOGD = true;
// TODO: remove this testing code
+ private static final boolean TEST_ANIM = false;
private static final boolean TEST_RADIOS = false;
private static final String TEST_RADIOS_PROP = "test.radios";
@@ -175,10 +176,12 @@
private CheckBox mDisableAtLimit;
private View mDisableAtLimitView;
+ private View mCycleView;
private Spinner mCycleSpinner;
private CycleAdapter mCycleAdapter;
private DataUsageChartView mChart;
+ private TextView mUsageSummary;
private View mAppDetail;
private TextView mAppTitle;
@@ -272,7 +275,8 @@
}
// bind cycle dropdown
- mCycleSpinner = (Spinner) mHeader.findViewById(R.id.cycles);
+ mCycleView = mHeader.findViewById(R.id.cycles);
+ mCycleSpinner = (Spinner) mCycleView.findViewById(R.id.cycles_spinner);
mCycleAdapter = new CycleAdapter(context);
mCycleSpinner.setAdapter(mCycleAdapter);
mCycleSpinner.setOnItemSelectedListener(mCycleListener);
@@ -282,12 +286,12 @@
{
// bind app detail controls
- mAppDetail = view.findViewById(R.id.app_detail);
- mAppTitle = (TextView) view.findViewById(R.id.app_title);
- mAppSubtitle = (TextView) view.findViewById(R.id.app_subtitle);
- mAppSwitches = (LinearLayout) view.findViewById(R.id.app_switches);
+ mAppDetail = mHeader.findViewById(R.id.app_detail);
+ mAppTitle = (TextView) mAppDetail.findViewById(R.id.app_title);
+ mAppSubtitle = (TextView) mAppDetail.findViewById(R.id.app_subtitle);
+ mAppSwitches = (LinearLayout) mAppDetail.findViewById(R.id.app_switches);
- mAppSettings = (Button) view.findViewById(R.id.app_settings);
+ mAppSettings = (Button) mAppDetail.findViewById(R.id.app_settings);
mAppSettings.setOnClickListener(mAppSettingsListener);
mAppRestrict = new CheckBox(inflater.getContext());
@@ -300,8 +304,10 @@
mAppSwitches.addView(mAppRestrictView);
}
+ mUsageSummary = (TextView) mHeader.findViewById(R.id.usage_summary);
+
// only assign layout transitions once first layout is finished
- mHeader.getViewTreeObserver().addOnGlobalLayoutListener(mFirstLayoutListener);
+ mListView.getViewTreeObserver().addOnGlobalLayoutListener(mFirstLayoutListener);
mAdapter = new DataUsageAdapter();
mListView.setOnItemClickListener(mListListener);
@@ -443,19 +449,28 @@
private OnGlobalLayoutListener mFirstLayoutListener = new OnGlobalLayoutListener() {
/** {@inheritDoc} */
public void onGlobalLayout() {
- mHeader.getViewTreeObserver().removeGlobalOnLayoutListener(mFirstLayoutListener);
+ mListView.getViewTreeObserver().removeGlobalOnLayoutListener(mFirstLayoutListener);
- mTabsContainer.setLayoutTransition(new LayoutTransition());
- mHeader.setLayoutTransition(new LayoutTransition());
- mNetworkSwitchesContainer.setLayoutTransition(new LayoutTransition());
+ mTabsContainer.setLayoutTransition(buildLayoutTransition());
+ mHeader.setLayoutTransition(buildLayoutTransition());
+ mNetworkSwitchesContainer.setLayoutTransition(buildLayoutTransition());
- final LayoutTransition chartTransition = new LayoutTransition();
+ final LayoutTransition chartTransition = buildLayoutTransition();
chartTransition.setStartDelay(LayoutTransition.APPEARING, 0);
chartTransition.setStartDelay(LayoutTransition.DISAPPEARING, 0);
mChart.setLayoutTransition(chartTransition);
}
};
+ private static LayoutTransition buildLayoutTransition() {
+ final LayoutTransition transition = new LayoutTransition();
+ if (TEST_ANIM) {
+ transition.setDuration(1500);
+ }
+ transition.setAnimateParentHierarchy(false);
+ return transition;
+ }
+
/**
* Rebuild all tabs based on {@link NetworkPolicyEditor} and
* {@link #mShowWifi}, hiding the tabs entirely when applicable. Selects
@@ -668,7 +683,7 @@
updateDetailData();
final Context context = getActivity();
- if (NetworkPolicyManager.isUidValidForPolicy(context, mUid)) {
+ if (NetworkPolicyManager.isUidValidForPolicy(context, mUid) && !getRestrictBackground()) {
mAppRestrictView.setVisibility(View.VISIBLE);
mAppRestrict.setChecked(getAppRestrictBackground());
@@ -710,13 +725,22 @@
}
private boolean getRestrictBackground() {
- return !mConnService.getBackgroundDataSetting();
+ try {
+ return mPolicyService.getRestrictBackground();
+ } catch (RemoteException e) {
+ Log.w(TAG, "problem talking with policy service: " + e);
+ return false;
+ }
}
private void setRestrictBackground(boolean restrictBackground) {
if (LOGD) Log.d(TAG, "setRestrictBackground()");
- mConnService.setBackgroundDataSetting(!restrictBackground);
- mMenuRestrictBackground.setChecked(restrictBackground);
+ try {
+ mPolicyService.setRestrictBackground(restrictBackground);
+ mMenuRestrictBackground.setChecked(restrictBackground);
+ } catch (RemoteException e) {
+ Log.w(TAG, "problem talking with policy service: " + e);
+ }
}
private boolean getAppRestrictBackground() {
@@ -732,7 +756,7 @@
}
private void setAppRestrictBackground(boolean restrictBackground) {
- if (LOGD) Log.d(TAG, "setRestrictBackground()");
+ if (LOGD) Log.d(TAG, "setAppRestrictBackground()");
try {
mPolicyService.setUidPolicy(
mUid, restrictBackground ? POLICY_REJECT_METERED_BACKGROUND : POLICY_NONE);
@@ -909,7 +933,7 @@
// update chart to show selected cycle, and update detail data
// to match updated sweep bounds.
- mChart.setVisibleRange(cycle.start, cycle.end, mHistory.getEnd());
+ mChart.setVisibleRange(cycle.start, cycle.end);
updateDetailData();
}
@@ -932,28 +956,40 @@
final long start = mChart.getInspectStart();
final long end = mChart.getInspectEnd();
+ final long now = System.currentTimeMillis();
+
+ final Context context = getActivity();
+ final NetworkStatsHistory.Entry entry;
if (isAppDetailMode()) {
if (mDetailHistory != null) {
- final Context context = mChart.getContext();
- final long now = System.currentTimeMillis();
- final NetworkStatsHistory.Entry entry = mDetailHistory.getValues(
- start, end, now, null);
+ entry = mDetailHistory.getValues(start, end, now, null);
mAppSubtitle.setText(
getString(R.string.data_usage_received_sent,
Formatter.formatFileSize(context, entry.rxBytes),
Formatter.formatFileSize(context, entry.txBytes)));
+ } else {
+ entry = null;
}
getLoaderManager().destroyLoader(LOADER_SUMMARY);
} else {
+ entry = mHistory.getValues(start, end, now, null);
+
// kick off loader for detailed stats
getLoaderManager().restartLoader(LOADER_SUMMARY,
SummaryForAllUidLoader.buildArgs(mTemplate, start, end), mSummaryForAllUid);
}
+
+ final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0;
+ final String totalPhrase = Formatter.formatFileSize(context, totalBytes);
+ final String rangePhrase = formatDateRangeUtc(context, start, end);
+
+ mUsageSummary.setText(
+ getString(R.string.data_usage_total_during_range, totalPhrase, rangePhrase));
}
private final LoaderCallbacks<NetworkStats> mSummaryForAllUid = new LoaderCallbacks<
@@ -1022,10 +1058,6 @@
public long start;
public long end;
- private static final StringBuilder sBuilder = new StringBuilder(50);
- private static final java.util.Formatter sFormatter = new java.util.Formatter(
- sBuilder, Locale.getDefault());
-
CycleItem(CharSequence label) {
this.label = label;
}
@@ -1036,21 +1068,30 @@
this.end = end;
}
- private static String formatDateRangeUtc(Context context, long start, long end) {
- synchronized (sBuilder) {
- sBuilder.setLength(0);
- return DateUtils.formatDateRange(context, sFormatter, start, end,
- DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH,
- Time.TIMEZONE_UTC).toString();
- }
- }
-
@Override
public String toString() {
return label.toString();
}
}
+ private static final StringBuilder sBuilder = new StringBuilder(50);
+ private static final java.util.Formatter sFormatter = new java.util.Formatter(
+ sBuilder, Locale.getDefault());
+
+ private static String formatDateRangeUtc(Context context, long start, long end) {
+ synchronized (sBuilder) {
+ int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH;
+ if (Time.getJulianDay(start, 0) == Time.getJulianDay(end, 0)) {
+ // when times are on same day, include time detail
+ flags |= DateUtils.FORMAT_SHOW_TIME;
+ }
+
+ sBuilder.setLength(0);
+ return DateUtils.formatDateRange(
+ context, sFormatter, start, end, flags, Time.TIMEZONE_UTC).toString();
+ }
+ }
+
/**
* Special-case data usage cycle that triggers dialog to change
* {@link NetworkPolicy#cycleDay}.
@@ -1366,7 +1407,7 @@
/**
* Dialog to request user confirmation before setting
- * {@link ConnectivityManager#setBackgroundDataSetting(boolean)}.
+ * {@link INetworkPolicyManager#setRestrictBackground(boolean)}.
*/
public static class ConfirmRestrictFragment extends DialogFragment {
public static void show(DataUsageSummary parent) {
diff --git a/src/com/android/settings/PrivacySettings.java b/src/com/android/settings/PrivacySettings.java
index 28dc93a..6759500 100644
--- a/src/com/android/settings/PrivacySettings.java
+++ b/src/com/android/settings/PrivacySettings.java
@@ -43,11 +43,13 @@
private static final String BACKUP_DATA = "backup_data";
private static final String AUTO_RESTORE = "auto_restore";
private static final String CONFIGURE_ACCOUNT = "configure_account";
+ private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
private IBackupManager mBackupManager;
private CheckBoxPreference mBackup;
private CheckBoxPreference mAutoRestore;
private Dialog mConfirmDialog;
private PreferenceScreen mConfigure;
+ private PreferenceScreen mPassword;
private static final int DIALOG_ERASE_BACKUP = 2;
private int mDialogType;
@@ -64,6 +66,7 @@
mBackup = (CheckBoxPreference) screen.findPreference(BACKUP_DATA);
mAutoRestore = (CheckBoxPreference) screen.findPreference(AUTO_RESTORE);
mConfigure = (PreferenceScreen) screen.findPreference(CONFIGURE_ACCOUNT);
+ mPassword = (PreferenceScreen) screen.findPreference(LOCAL_BACKUP_PASSWORD);
// Vendor specific
if (getActivity().getPackageManager().
@@ -158,7 +161,9 @@
mConfigure.setEnabled(configureEnabled);
mConfigure.setIntent(configIntent);
setConfigureSummary(configSummary);
- }
+
+ updatePasswordSummary();
+}
private void setConfigureSummary(String summary) {
if (summary != null) {
@@ -178,6 +183,18 @@
}
}
+ private void updatePasswordSummary() {
+ try {
+ if (mBackupManager.hasBackupPassword()) {
+ mPassword.setSummary(R.string.local_backup_password_summary_change);
+ } else {
+ mPassword.setSummary(R.string.local_backup_password_summary_none);
+ }
+ } catch (RemoteException e) {
+ // Not much we can do here
+ }
+ }
+
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
//updateProviders();
diff --git a/src/com/android/settings/SetFullBackupPassword.java b/src/com/android/settings/SetFullBackupPassword.java
new file mode 100644
index 0000000..9f3f29f
--- /dev/null
+++ b/src/com/android/settings/SetFullBackupPassword.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 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.settings;
+
+import android.app.Activity;
+import android.app.backup.IBackupManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class SetFullBackupPassword extends Activity {
+ static final String TAG = "SetFullBackupPassword";
+
+ IBackupManager mBackupManager;
+ TextView mCurrentPw, mNewPw, mConfirmNewPw;
+ Button mCancel, mSet;
+
+ OnClickListener mButtonListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (v == mSet) {
+ final String curPw = mCurrentPw.getText().toString();
+ final String newPw = mNewPw.getText().toString();
+ final String confirmPw = mConfirmNewPw.getText().toString();
+
+ if (!newPw.equals(confirmPw)) {
+ // Mismatch between new pw and its confirmation re-entry
+Log.i(TAG, "password mismatch");
+ Toast.makeText(SetFullBackupPassword.this,
+ "!!! New password and confirmation don't match !!!",
+ Toast.LENGTH_LONG).show();
+ return;
+ }
+
+ // TODO: should we distinguish cases of has/hasn't set a pw before?
+
+ if (setBackupPassword(curPw, newPw)) {
+ // success
+Log.i(TAG, "password set successfully");
+ Toast.makeText(SetFullBackupPassword.this,
+ "!!! New backup password set !!!",
+ Toast.LENGTH_LONG).show();
+ finish();
+ } else {
+ // failure -- bad existing pw, usually
+Log.i(TAG, "failure; password mismatch?");
+ Toast.makeText(SetFullBackupPassword.this,
+ "!!! Failure setting backup password !!!",
+ Toast.LENGTH_LONG).show();
+ }
+ } else if (v == mCancel) {
+ finish();
+ } else {
+ Log.w(TAG, "Click on unknown view");
+ }
+ }
+ };
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mBackupManager = IBackupManager.Stub.asInterface(ServiceManager.getService("backup"));
+
+ setContentView(R.layout.set_backup_pw);
+
+ mCurrentPw = (TextView) findViewById(R.id.current_backup_pw);
+ mNewPw = (TextView) findViewById(R.id.new_backup_pw);
+ mConfirmNewPw = (TextView) findViewById(R.id.confirm_new_backup_pw);
+
+ mCancel = (Button) findViewById(R.id.backup_pw_cancel_button);
+ mSet = (Button) findViewById(R.id.backup_pw_set_button);
+
+ mCancel.setOnClickListener(mButtonListener);
+ mSet.setOnClickListener(mButtonListener);
+ }
+
+ private boolean setBackupPassword(String currentPw, String newPw) {
+ try {
+ return mBackupManager.setBackupPassword(currentPw, newPw);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to communicate with backup manager");
+ return false;
+ }
+ }
+}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index ae7e24e..443705f 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -600,4 +600,5 @@
public static class DataUsageSummaryActivity extends Settings { /* empty */ }
public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }
public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }
+ public static class NfcSharingSettingsActivity extends Settings { /* empty */ }
}
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index beab491..7efa15d 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -54,6 +54,7 @@
private AirplaneModeEnabler mAirplaneModeEnabler;
private CheckBoxPreference mAirplaneModePreference;
private NfcEnabler mNfcEnabler;
+ private NfcAdapter mNfcAdapter;
/**
* Invoked on each preference click in this hierarchy, overrides
@@ -113,7 +114,8 @@
}
// Remove NFC if its not available
- if (NfcAdapter.getDefaultAdapter(activity) == null) {
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(activity);
+ if (mNfcAdapter == null) {
getPreferenceScreen().removePreference(nfc);
getPreferenceScreen().removePreference(zeroclick);
}
@@ -175,6 +177,18 @@
mAirplaneModeEnabler.resume();
mNfcEnabler.resume();
+
+ if (mNfcAdapter != null) {
+ // Update zero-click subtitle
+ Preference zeroClick = getPreferenceScreen().
+ findPreference(KEY_ZEROCLICK_SETTINGS);
+
+ if (mNfcAdapter.zeroClickEnabled()) {
+ zeroClick.setSummary(R.string.zeroclick_on_summary);
+ } else {
+ zeroClick.setSummary(R.string.zeroclick_off_summary);
+ }
+ }
}
@Override
diff --git a/src/com/android/settings/nfc/ZeroClick.java b/src/com/android/settings/nfc/ZeroClick.java
index 7868662..4d657d9 100644
--- a/src/com/android/settings/nfc/ZeroClick.java
+++ b/src/com/android/settings/nfc/ZeroClick.java
@@ -16,28 +16,54 @@
package com.android.settings.nfc;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.Fragment;
-import android.content.ContentResolver;
import android.nfc.NfcAdapter;
import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.Preference;
-import android.provider.Settings;
+import android.preference.PreferenceActivity;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.CheckBox;
import android.widget.CompoundButton;
-import android.widget.EditText;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.util.Log;
+import android.widget.Switch;
import com.android.settings.R;
public class ZeroClick extends Fragment
implements CompoundButton.OnCheckedChangeListener {
private View mView;
- private CheckBox mCheckbox;
private NfcAdapter mNfcAdapter;
+ private Switch mActionBarSwitch;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Activity activity = getActivity();
+
+ mActionBarSwitch = new Switch(activity);
+
+ if (activity instanceof PreferenceActivity) {
+ PreferenceActivity preferenceActivity = (PreferenceActivity) activity;
+ if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {
+ final int padding = activity.getResources().getDimensionPixelSize(
+ R.dimen.action_bar_switch_padding);
+ mActionBarSwitch.setPadding(0, 0, padding, 0);
+ activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
+ ActionBar.DISPLAY_SHOW_CUSTOM);
+ activity.getActionBar().setCustomView(mActionBarSwitch, new ActionBar.LayoutParams(
+ ActionBar.LayoutParams.WRAP_CONTENT,
+ ActionBar.LayoutParams.WRAP_CONTENT,
+ Gravity.CENTER_VERTICAL | Gravity.RIGHT));
+ }
+ }
+
+ mActionBarSwitch.setOnCheckedChangeListener(this);
+
+ mNfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
+ mActionBarSwitch.setChecked(mNfcAdapter.zeroClickEnabled());
+ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -48,10 +74,9 @@
}
private void initView(View view) {
- mCheckbox = (CheckBox) mView.findViewById(R.id.zeroclick_checkbox);
- mCheckbox.setOnCheckedChangeListener(this);
mNfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
- mCheckbox.setChecked(mNfcAdapter.zeroClickEnabled());
+ mActionBarSwitch.setOnCheckedChangeListener(this);
+ mActionBarSwitch.setChecked(mNfcAdapter.zeroClickEnabled());
}
@Override
@@ -67,15 +92,15 @@
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean desiredState) {
boolean success = false;
- mCheckbox.setEnabled(false);
+ mActionBarSwitch.setEnabled(false);
if (desiredState) {
success = mNfcAdapter.enableZeroClick();
} else {
success = mNfcAdapter.disableZeroClick();
}
if (success) {
- mCheckbox.setChecked(desiredState);
+ mActionBarSwitch.setChecked(desiredState);
}
- mCheckbox.setEnabled(true);
+ mActionBarSwitch.setEnabled(true);
}
}
diff --git a/src/com/android/settings/vpn2/VpnDialog.java b/src/com/android/settings/vpn2/VpnDialog.java
index d644700..c1a4531 100644
--- a/src/com/android/settings/vpn2/VpnDialog.java
+++ b/src/com/android/settings/vpn2/VpnDialog.java
@@ -27,15 +27,18 @@
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
+import android.view.WindowManager;
import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.TextView;
-class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListener {
+import java.net.InetAddress;
+
+class VpnDialog extends AlertDialog implements TextWatcher,
+ View.OnClickListener, AdapterView.OnItemSelectedListener {
private final KeyStore mKeyStore = KeyStore.getInstance();
private final DialogInterface.OnClickListener mListener;
private final VpnProfile mProfile;
@@ -50,6 +53,7 @@
private TextView mUsername;
private TextView mPassword;
private TextView mSearchDomains;
+ private TextView mDnsServers;
private TextView mRoutes;
private CheckBox mMppe;
private TextView mL2tpSecret;
@@ -82,6 +86,7 @@
mUsername = (TextView) mView.findViewById(R.id.username);
mPassword = (TextView) mView.findViewById(R.id.password);
mSearchDomains = (TextView) mView.findViewById(R.id.search_domains);
+ mDnsServers = (TextView) mView.findViewById(R.id.dns_servers);
mRoutes = (TextView) mView.findViewById(R.id.routes);
mMppe = (CheckBox) mView.findViewById(R.id.mppe);
mL2tpSecret = (TextView) mView.findViewById(R.id.l2tp_secret);
@@ -98,6 +103,7 @@
mUsername.setText(mProfile.username);
mPassword.setText(mProfile.password);
mSearchDomains.setText(mProfile.searchDomains);
+ mDnsServers.setText(mProfile.dnsServers);
mRoutes.setText(mProfile.routes);
mMppe.setChecked(mProfile.mppe);
mL2tpSecret.setText(mProfile.l2tpSecret);
@@ -115,6 +121,8 @@
mServer.addTextChangedListener(this);
mUsername.addTextChangedListener(this);
mPassword.addTextChangedListener(this);
+ mDnsServers.addTextChangedListener(this);
+ mRoutes.addTextChangedListener(this);
mIpsecSecret.addTextChangedListener(this);
mIpsecUserCert.setOnItemSelectedListener(this);
@@ -131,6 +139,15 @@
// Show type-specific fields.
changeType(mProfile.type);
+ // Show advanced options directly if any of them is set.
+ View showOptions = mView.findViewById(R.id.show_options);
+ if (mProfile.searchDomains.isEmpty() && mProfile.dnsServers.isEmpty() &&
+ mProfile.routes.isEmpty()) {
+ showOptions.setOnClickListener(this);
+ } else {
+ onClick(showOptions);
+ }
+
// Create a button to save the profile.
setButton(DialogInterface.BUTTON_POSITIVE,
context.getString(R.string.vpn_save), mListener);
@@ -155,6 +172,10 @@
// Disable the action button if necessary.
getButton(DialogInterface.BUTTON_POSITIVE)
.setEnabled(mEditing ? valid : validate(false));
+
+ // Workaround to resize the dialog for the input method.
+ getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
@Override
@@ -171,6 +192,12 @@
}
@Override
+ public void onClick(View showOptions) {
+ showOptions.setVisibility(View.GONE);
+ mView.findViewById(R.id.options).setVisibility(View.VISIBLE);
+ }
+
+ @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent == mType) {
changeType(position);
@@ -221,7 +248,9 @@
if (!editing) {
return mUsername.getText().length() != 0 && mPassword.getText().length() != 0;
}
- if (mName.getText().length() == 0 || mServer.getText().length() == 0) {
+ if (mName.getText().length() == 0 || mServer.getText().length() == 0 ||
+ !validateAddresses(mDnsServers.getText().toString(), false) ||
+ !validateAddresses(mRoutes.getText().toString(), true)) {
return false;
}
switch (mType.getSelectedItemPosition()) {
@@ -239,6 +268,33 @@
return false;
}
+ private boolean validateAddresses(String addresses, boolean cidr) {
+ try {
+ for (String address : addresses.split(" ")) {
+ if (address.isEmpty()) {
+ continue;
+ }
+ // Legacy VPN currently only supports IPv4.
+ int prefixLength = 32;
+ if (cidr) {
+ String[] parts = address.split("/", 2);
+ address = parts[0];
+ prefixLength = Integer.parseInt(parts[1]);
+ }
+ byte[] bytes = InetAddress.parseNumericAddress(address).getAddress();
+ int integer = (bytes[3] & 0xFF) | (bytes[2] & 0xFF) << 8 |
+ (bytes[1] & 0xFF) << 16 | (bytes[0] & 0xFF) << 24;
+ if (bytes.length != 4 || prefixLength < 0 || prefixLength > 32 ||
+ (prefixLength < 32 && (integer << prefixLength) != 0)) {
+ return false;
+ }
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) {
Context context = getContext();
String first = (firstId == 0) ? "" : context.getString(firstId);
@@ -279,6 +335,7 @@
profile.username = mUsername.getText().toString();
profile.password = mPassword.getText().toString();
profile.searchDomains = mSearchDomains.getText().toString().trim();
+ profile.dnsServers = mDnsServers.getText().toString().trim();
profile.routes = mRoutes.getText().toString().trim();
// Then, save type-specific fields.
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index 4dbb6bd..2ab99e8 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -108,7 +108,7 @@
Credentials.getInstance().unlock(getActivity());
} else {
// We already tried, but it is still not working!
- getActivity().getFragmentManager().popBackStack();
+ finishFragment();
}
mUnlocking = !mUnlocking;
return;
@@ -429,8 +429,11 @@
config.interfaze = interfaze;
config.session = profile.name;
config.routes = profile.routes;
+ if (!profile.dnsServers.isEmpty()) {
+ config.dnsServers = Arrays.asList(profile.dnsServers.split(" +"));
+ }
if (!profile.searchDomains.isEmpty()) {
- config.searchDomains = Arrays.asList(profile.searchDomains.split(" "));
+ config.searchDomains = Arrays.asList(profile.searchDomains.split(" +"));
}
mService.startLegacyVpn(config, racoon, mtpd);
diff --git a/src/com/android/settings/widget/ChartSweepView.java b/src/com/android/settings/widget/ChartSweepView.java
index 4e37657..99c35bd 100644
--- a/src/com/android/settings/widget/ChartSweepView.java
+++ b/src/com/android/settings/widget/ChartSweepView.java
@@ -61,8 +61,11 @@
private ChartAxis mAxis;
private long mValue;
- private ChartSweepView mClampAfter;
- private ChartSweepView mClampBefore;
+ private long mValidAfter;
+ private long mValidBefore;
+ private ChartSweepView mValidAfterDynamic;
+ private ChartSweepView mValidBeforeDynamic;
+ private long mValidBufferArea;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
@@ -259,12 +262,25 @@
}
}
- public void setClampAfter(ChartSweepView clampAfter) {
- mClampAfter = clampAfter;
+ /**
+ * Set valid range this sweep can move within, in {@link #mAxis} values. The
+ * most restrictive combination of all valid ranges is used.
+ */
+ public void setValidRange(long validAfter, long validBefore) {
+ mValidAfter = validAfter;
+ mValidBefore = validBefore;
}
- public void setClampBefore(ChartSweepView clampBefore) {
- mClampBefore = clampBefore;
+ /**
+ * Set valid range this sweep can move within, defined by the given
+ * {@link ChartSweepView}. The most restrictive combination of all valid
+ * ranges is used.
+ */
+ public void setValidRangeDynamic(
+ ChartSweepView validAfter, ChartSweepView validBefore, long bufferArea) {
+ mValidAfterDynamic = validAfter;
+ mValidBeforeDynamic = validBefore;
+ mValidBufferArea = bufferArea;
}
@Override
@@ -285,6 +301,12 @@
if (accept) {
mTracking = event.copy();
+
+ // starting drag should activate entire chart
+ if (!parent.isActivated()) {
+ parent.setActivated(true);
+ }
+
return true;
} else {
return false;
@@ -336,31 +358,52 @@
}
}
+ @Override
+ public void addOnLayoutChangeListener(OnLayoutChangeListener listener) {
+ // ignored to keep LayoutTransition from animating us
+ }
+
+ @Override
+ public void removeOnLayoutChangeListener(OnLayoutChangeListener listener) {
+ // ignored to keep LayoutTransition from animating us
+ }
+
+ private long getValidAfterValue() {
+ final ChartSweepView dynamic = mValidAfterDynamic;
+ final boolean dynamicEnabled = dynamic != null && dynamic.isEnabled();
+ return Math.max(mValidAfter,
+ dynamicEnabled ? dynamic.getValue() + mValidBufferArea : Long.MIN_VALUE);
+ }
+
+ private long getValidBeforeValue() {
+ final ChartSweepView dynamic = mValidBeforeDynamic;
+ final boolean dynamicEnabled = dynamic != null && dynamic.isEnabled();
+ return Math.min(mValidBefore,
+ dynamicEnabled ? dynamic.getValue() - mValidBufferArea : Long.MAX_VALUE);
+ }
+
/**
* Compute {@link Rect} in {@link #getParent()} coordinates that we should
- * be clamped inside of, usually from {@link #setClampAfter(ChartSweepView)}
+ * be clamped inside of, usually from {@link #setValidRange(long, long)}
* style rules.
*/
private Rect computeClampRect(Rect parentContent) {
final Rect clampRect = new Rect(parentContent);
- final ChartSweepView after = mClampAfter;
- final ChartSweepView before = mClampBefore;
+ float validAfterPoint = mAxis.convertToPoint(getValidAfterValue());
+ float validBeforePoint = mAxis.convertToPoint(getValidBeforeValue());
+ if (validAfterPoint > validBeforePoint) {
+ float swap = validBeforePoint;
+ validBeforePoint = validAfterPoint;
+ validAfterPoint = swap;
+ }
if (mFollowAxis == VERTICAL) {
- if (after != null) {
- clampRect.top += after.getPoint();
- }
- if (before != null) {
- clampRect.bottom -= clampRect.height() - before.getPoint();
- }
+ clampRect.bottom = clampRect.top + (int) validBeforePoint;
+ clampRect.top += validAfterPoint;
} else {
- if (after != null) {
- clampRect.left += after.getPoint();
- }
- if (before != null) {
- clampRect.right -= clampRect.width() - before.getPoint();
- }
+ clampRect.right = clampRect.left + (int) validBeforePoint;
+ clampRect.left += validAfterPoint;
}
return clampRect;
}
diff --git a/src/com/android/settings/widget/DataUsageChartView.java b/src/com/android/settings/widget/DataUsageChartView.java
index affede0..839171e 100644
--- a/src/com/android/settings/widget/DataUsageChartView.java
+++ b/src/com/android/settings/widget/DataUsageChartView.java
@@ -16,6 +16,8 @@
package com.android.settings.widget;
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+
import android.content.Context;
import android.content.res.Resources;
import android.net.NetworkPolicy;
@@ -47,6 +49,8 @@
private ChartNetworkSeriesView mSeries;
private ChartNetworkSeriesView mDetailSeries;
+ private NetworkStatsHistory mHistory;
+
private ChartSweepView mSweepLeft;
private ChartSweepView mSweepRight;
private ChartSweepView mSweepWarning;
@@ -88,10 +92,14 @@
mSweepWarning = (ChartSweepView) findViewById(R.id.sweep_warning);
// prevent sweeps from crossing each other
- mSweepLeft.setClampBefore(mSweepRight);
- mSweepRight.setClampAfter(mSweepLeft);
- mSweepLimit.setClampBefore(mSweepWarning);
- mSweepWarning.setClampAfter(mSweepLimit);
+ mSweepLeft.setValidRangeDynamic(null, mSweepRight, HOUR_IN_MILLIS);
+ mSweepRight.setValidRangeDynamic(mSweepLeft, null, HOUR_IN_MILLIS);
+
+ // TODO: assign these ranges as user changes data axis
+ mSweepWarning.setValidRange(0L, 5 * GB_IN_BYTES);
+ mSweepWarning.setValidRangeDynamic(null, mSweepLimit, MB_IN_BYTES);
+ mSweepLimit.setValidRange(0L, 5 * GB_IN_BYTES);
+ mSweepLimit.setValidRangeDynamic(mSweepWarning, null, MB_IN_BYTES);
mSweepLeft.addOnSweepListener(mSweepListener);
mSweepRight.addOnSweepListener(mSweepListener);
@@ -116,6 +124,7 @@
public void bindNetworkStats(NetworkStatsHistory stats) {
mSeries.bindNetworkStats(stats);
+ mHistory = stats;
updatePrimaryRange();
requestLayout();
}
@@ -197,15 +206,6 @@
}
}
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (!isActivated()) {
- return true;
- } else {
- return super.onInterceptTouchEvent(ev);
- }
- }
-
public long getInspectStart() {
return mSweepLeft.getValue();
}
@@ -222,18 +222,33 @@
return mSweepLimit.getValue();
}
+ private long getStatsStart() {
+ return mHistory != null ? mHistory.getStart() : Long.MIN_VALUE;
+ }
+
+ private long getStatsEnd() {
+ return mHistory != null ? mHistory.getEnd() : Long.MAX_VALUE;
+ }
+
/**
* Set the exact time range that should be displayed, updating how
* {@link ChartNetworkSeriesView} paints. Moves inspection ranges to be the
* last "week" of available data, without triggering listener events.
*/
- public void setVisibleRange(long start, long end, long dataBoundary) {
- mHoriz.setBounds(start, end);
+ public void setVisibleRange(long visibleStart, long visibleEnd) {
+ mHoriz.setBounds(visibleStart, visibleEnd);
+
+ final long validStart = Math.max(visibleStart, getStatsStart());
+ final long validEnd = Math.min(visibleEnd, getStatsEnd());
+
+ // prevent time sweeps from leaving valid data
+ mSweepLeft.setValidRange(validStart, validEnd);
+ mSweepRight.setValidRange(validStart, validEnd);
// default sweeps to last week of data
- final long halfRange = (end + start) / 2;
- final long sweepMax = Math.min(end, dataBoundary);
- final long sweepMin = Math.max(start, (sweepMax - DateUtils.WEEK_IN_MILLIS));
+ final long halfRange = (visibleEnd + visibleStart) / 2;
+ final long sweepMax = validEnd;
+ final long sweepMin = Math.max(visibleStart, (sweepMax - DateUtils.WEEK_IN_MILLIS));
mSweepLeft.setValue(sweepMin);
mSweepRight.setValue(sweepMax);
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 897280f..876fd99 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -112,8 +112,8 @@
private TextView mProxyPortView;
private TextView mProxyExclusionListView;
- private IpAssignment mIpAssignment;
- private ProxySettings mProxySettings;
+ private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED;
+ private ProxySettings mProxySettings = ProxySettings.UNASSIGNED;
private LinkProperties mLinkProperties = new LinkProperties();
// True when this instance is used in SetupWizard XL context.