diff --git a/Android.mk b/Android.mk
index dedda011ccc..b7bc093fc52 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,14 +1,19 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := user
+LOCAL_JAVA_LIBRARIES := bouncycastle
+LOCAL_STATIC_JAVA_LIBRARIES := guava
+
+LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := Settings
LOCAL_CERTIFICATE := platform
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
include $(BUILD_PACKAGE)
-# Use the folloing include to make our test apk.
+# Use the following include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1500d8b34c5..3a835c1cb22 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,24 +1,32 @@
Sdílené datové připojení prostřednictvím portu USB
+Propojíte-li počítač a telefon kabelem USB, můžete připojení k internetu svého telefonu sdílet s připojeným počítačem. +Sdílení datového připojení prostřednictvím sítě WiFi
+Telefon může sloužit jako přístupový bod sítě WiFi. Připojení k internetu svého telefonu můžete sdílet hned s několika počítači nebo jinými zařízeními. +Sdílené datové připojení prostřednictvím portu USB
+Propojíte-li počítač a telefon kabelem USB, můžete připojení k internetu svého telefonu sdílet s připojeným počítačem. +Sdílení datového připojení prostřednictvím sítě WiFi
+Telefon může sloužit jako přístupový bod sítě WiFi. Připojení k internetu svého telefonu můžete sdílet hned s několika počítači nebo jinými zařízeními. +USB-tethering
+Du kan tether din telefon til din computer med et USB-kabel for at dele din telefons internetforbindelse med din computer +Wi-Fi-tethering
+Du kan gøre din telefon til et Wi-Fi-adgangspunkt, så du kan dele din telefons internetforbindelse med en eller flere computere eller andre enheder +USB-tethering
+Du kan tether din telefon til din computer med et USB-kabel for at dele din telefons internetforbindelse med din computer +Wi-Fi-tethering
+Du kan gøre din telefon til et Wi-Fi-adgangspunkt, så du kan dele din telefons internetforbindelse med en eller flere computere eller andre enheder +USB-Tethering
+Sie können Ihr Telefon über ein USB-Kabel mit Ihrem Computer verbinden, um die Internetverbindung auf Ihrem Telefon auf Ihrem Computer nutzen zu können. +Wi-Fi-Tethering
+Sie können Ihr Telefon in einen Wi-Fi-Zugangspunkt verwandeln, um die Internetverbindung Ihres Telefons auf einem oder mehreren Computern bzw. anderen Geräten nutzen zu können. +USB-Tethering
+Sie können Ihr Telefon über ein USB-Kabel mit Ihrem Computer verbinden, um die Internetverbindung auf Ihrem Telefon auf Ihrem Computer nutzen zu können. +Wi-Fi-Tethering
+Sie können Ihr Telefon in einen Wi-Fi-Zugangspunkt verwandeln, um die Internetverbindung Ihres Telefons auf einem oder mehreren Computern bzw. anderen Geräten nutzen zu können. +Σύνδεση μέσω κινητής συσκευής με USB
+Μπορείτε να συνδέσετε το τηλέφωνο με τον υπολογιστή σας με ένα καλώδιο USB, για κοινή χρήση της σύνδεσης στο Διαδίκτυο του τηλεφώνου σας με τον υπολογιστή σας +Σύνδεση μέσω κινητής συσκευής με Wi-Fi
+Μπορείτε να μετατρέψετε το τηλέφωνό σας σε ένα σημείο πρόσβασης Wi-Fi, για κοινή χρήση της σύνδεσης στο Διαδίκτυο του τηλεφώνου σας με έναν ή περισσότερους υπολογιστές ή άλλες συσκευές +Σύνδεση μέσω κινητής συσκευής με USB
+Μπορείτε να συνδέσετε το τηλέφωνο με τον υπολογιστή σας με ένα καλώδιο USB, για κοινή χρήση της σύνδεσης στο Διαδίκτυο του τηλεφώνου σας με τον υπολογιστή σας +Σύνδεση μέσω κινητής συσκευής με Wi-Fi
+Μπορείτε να μετατρέψετε το τηλέφωνό σας σε ένα σημείο πρόσβασης Wi-Fi, για κοινή χρήση της σύνδεσης στο Διαδίκτυο του τηλεφώνου σας με έναν ή περισσότερους υπολογιστές ή άλλες συσκευές +USB tethering
+You can tether your phone to your computer with a USB cable, to share your phone's Internet connection with your computer +Wi-Fi tethering
+You can turn your phone into a Wi-Fi access point, to share your phone's Internet connection with one or more computers or other devices +USB tethering
+You can tether your phone to your computer with a USB cable, to share your phone's Internet connection with your computer +Wi-Fi tethering
+You can turn your phone into a Wi-Fi access point, to share your phone's Internet connection with one or more computers or other devices +Bluetooth tethering
+You can tether your Android device to your computer via a Bluetooth connection, to share your device's Internet connection with your computer +USB tethering
+You can tether your Android device to your computer with a USB cable, to share your device's Internet connection with your computer +Bluetooth tethering
+You can tether your Android device to your computer via a Bluetooth connection, to share your device's Internet connection with your computer +Portable Wi-Fi hotspot
+You can turn your Android device into a portable Wi-Fi hotspot, to share your Android device's Internet connection with one or more computers or other devices +USB tethering
+You can tether your Android device to your computer with a USB cable, to share your device's Internet connection with your computer +Portable Wi-Fi hotspot
+You can turn your Android device into a portable Wi-Fi hotspot, to share your Android device's Internet connection with one or more computers or other devices +Anclaje de USB
+Puedes anclar el teléfono a tu ordenador con un cable USB para compartir la conexión a Internet del teléfono con el equipo. +Anclaje a red Wi-Fi
+Puedes convertir el teléfono en un punto de acceso Wi-Fi para compartir la conexión a Internet del teléfono con uno o con varios equipos o dispositivos. +Anclaje de USB
+Puedes anclar el teléfono a tu ordenador con un cable USB para compartir la conexión a Internet del teléfono con el equipo. +Anclaje a red Wi-Fi
+Puedes convertir el teléfono en un punto de acceso Wi-Fi para compartir la conexión a Internet del teléfono con uno o con varios equipos o dispositivos. +Anclaje a red USB
+Puedes anclar tu teléfono a tu computadora con un cable USB para compartir la conexión a Internet de tu teléfono con tu computadora. +Anclaje a redes de Wi-Fi
+Puedes cambiar tu teléfono a un punto de acceso Wi-Fi para compartir la conexión a Internet de tu teléfono con una computadora o un dispositivo, o más. +Anclaje a red USB
+Puedes anclar tu teléfono a tu computadora con un cable USB para compartir la conexión a Internet de tu teléfono con tu computadora. +Anclaje a redes de Wi-Fi
+Puedes cambiar tu teléfono a un punto de acceso Wi-Fi para compartir la conexión a Internet de tu teléfono con una computadora o un dispositivo, o más. +Partage de connexion par USB
+Vous pouvez partager la connexion Internet de votre mobile avec votre ordinateur, cela en connectant le téléphone à l'ordinateur par le biais d'un câble USB. +Partage de connexion via Wi-Fi
+Vous pouvez transformer votre mobile en point d'accès Wi-Fi et ainsi partager la connexion Internet du téléphone avec un ou plusieurs ordinateurs ou autres appareils. +Partage de connexion par USB
+Vous pouvez partager la connexion Internet de votre mobile avec votre ordinateur, cela en connectant le téléphone à l'ordinateur par le biais d'un câble USB. +Partage de connexion via Wi-Fi
+Vous pouvez transformer votre mobile en point d'accès Wi-Fi et ainsi partager la connexion Internet du téléphone avec un ou plusieurs ordinateurs ou autres appareils. +Tethering USB
+È possibile eseguire il tethering tra telefono e computer con un cavo USB per condividere la connessione Internet del cellulare con il computer. +Tethering Wi-Fi
+È possibile trasformare il telefono in un punto di accesso Wi-Fi per condividere la connessione Internet del cellulare con uno o più computer o altri dispositivi. +Tethering USB
+È possibile eseguire il tethering tra telefono e computer con un cavo USB per condividere la connessione Internet del cellulare con il computer. +Tethering Wi-Fi
+È possibile trasformare il telefono in un punto di accesso Wi-Fi per condividere la connessione Internet del cellulare con uno o più computer o altri dispositivi. +USB テザリング
+USB ケーブルを使って携帯端末をパソコンにテザリングし、端末のインターネット接続をパソコンと共有できます。 +Wi-Fi テザリング
+お使いの携帯端末を Wi-Fi アクセス ポイントとして利用し、端末のインターネット接続を 1 台以上のパソコンやその他の端末で共有できます。 +USB テザリング
+USB ケーブルを使って携帯端末をパソコンにテザリングし、端末のインターネット接続をパソコンと共有できます。 +Wi-Fi テザリング
+お使いの携帯端末を Wi-Fi アクセス ポイントとして利用し、端末のインターネット接続を 1 台以上のパソコンやその他の端末で共有できます。 +USB 테더링
+USB 케이블로 휴대전화를 컴퓨터에 테더링하여 휴대전화의 인터넷 연결을 컴퓨터와 공유할 수 있습니다. +Wi-Fi 테더링
+휴대전화를 Wi-Fi 액세스 포인트로 전환하여 휴대전화의 인터넷 연결을 하나 이상의 컴퓨터 또는 기타 기기와 공유할 수 있습니다. +USB 테더링
+USB 케이블로 휴대전화를 컴퓨터에 테더링하여 휴대전화의 인터넷 연결을 컴퓨터와 공유할 수 있습니다. +Wi-Fi 테더링
+휴대전화를 Wi-Fi 액세스 포인트로 전환하여 휴대전화의 인터넷 연결을 하나 이상의 컴퓨터 또는 기타 기기와 공유할 수 있습니다. +USB-tethering
+U kunt uw telefoon tetheren met een USB-kabel om de internetverbinding van uw telefoon te delen met uw computer +Wi-Fi-tethering
+U kunt uw telefoon gebruiken als Wi-Fi-toegangspunt om de internetverbinding van uw telefoon te delen met een of meer computers of andere apparaten +USB-tethering
+U kunt uw telefoon tetheren met een USB-kabel om de internetverbinding van uw telefoon te delen met uw computer +Wi-Fi-tethering
+U kunt uw telefoon gebruiken als Wi-Fi-toegangspunt om de internetverbinding van uw telefoon te delen met een of meer computers of andere apparaten +USB-tilknytning
+Du kan knytte telefonen til datamaskinen med en USB-kabel, slik at du kan dele telefonens Internett-tilkobling med maskinen +Tilknytning av trådløst nett
+Telefonen kan angis som et tilgangspunkt for trådløst nett for deling av Internett-tilkobling med én eller flere datamaskiner eller andre enheter +USB-tilknytning
+Du kan knytte telefonen til datamaskinen med en USB-kabel, slik at du kan dele telefonens Internett-tilkobling med maskinen +Tilknytning av trådløst nett
+Telefonen kan angis som et tilgangspunkt for trådløst nett for deling av Internett-tilkobling med én eller flere datamaskiner eller andre enheter +Powiązanie USB
+Telefon możesz powiązać z komputerem przy użyciu kabla USB, aby udostępniać na nim połączenie internetowe telefonu. +Powiązanie Wi-Fi
+Telefon możesz przekształcić w punkt dostępowy Wi-Fi, aby udostępniać połączenie internetowe telefonu jednemu lub większej liczbie komputerów i innych urządzeń. +Powiązanie USB
+Telefon możesz powiązać z komputerem przy użyciu kabla USB, aby udostępniać na nim połączenie internetowe telefonu. +Powiązanie Wi-Fi
+Telefon możesz przekształcić w punkt dostępowy Wi-Fi, aby udostępniać połączenie internetowe telefonu jednemu lub większej liczbie komputerów i innych urządzeń. +Vínculo USB
+Você pode vincular seu telefone ao seu computador com um cabo USB, compartilhando a conexão com a internet do telefone +Vínculo Wi-Fi
+Use seu telefone como um ponto de acesso Wi-Fi, compartilhando a conexão com a internet do telefone com computadores ou outros aparelhos +Vínculo USB
+Você pode vincular seu telefone ao seu computador com um cabo USB, compartilhando a conexão com a internet do telefone +Vínculo Wi-Fi
+Use seu telefone como um ponto de acesso Wi-Fi, compartilhando a conexão com a internet do telefone com computadores ou outros aparelhos +Associação USB
+Pode associar o seu telefone ao computador com um cabo USB, para partilhar com o computador a ligação à internet do telefone +Associação Wi-Fi
+Pode transformar o seu telefone num ponto de acesso Wi-Fi para partilhar a ligação à internet do telefone com um ou mais computadores ou outros dispositivos +Associação USB
+Pode associar o seu telefone ao computador com um cabo USB, para partilhar com o computador a ligação à internet do telefone +Associação Wi-Fi
+Pode transformar o seu telefone num ponto de acesso Wi-Fi para partilhar a ligação à internet do telefone com um ou mais computadores ou outros dispositivos +USB-подключение
+Вы можете подключить телефон к компьютеру с помощью USB-кабеля и предоставить компьютеру интернет-подключение, установленное посредством телефона. +Подключение Wi-Fi
+Телефон можно использовать как точку доступа Wi-Fi. В этом случае несколько компьютеров или других устройств смогут использовать интернет-подключение, установленное посредством телефона. +USB-подключение
+Вы можете подключить телефон к компьютеру с помощью USB-кабеля и предоставить компьютеру интернет-подключение, установленное посредством телефона. +Подключение Wi-Fi
+Телефон можно использовать как точку доступа Wi-Fi. В этом случае несколько компьютеров или других устройств смогут использовать интернет-подключение, установленное посредством телефона. +Internetdelning via USB
+Du kan ansluta telefonen till datorn med en USB-kabel om du vill dela telefonens Internetanslutning med datorn +Internetdelning via Wi-Fi
+Du kan göra din telefon till en åtkomstpunkt för Wi-FI om du vill dela telefonens Internetanslutning med en eller flera datorer eller enheter +Internetdelning via USB
+Du kan ansluta telefonen till datorn med en USB-kabel om du vill dela telefonens Internetanslutning med datorn +Internetdelning via Wi-Fi
+Du kan göra din telefon till en åtkomstpunkt för Wi-FI om du vill dela telefonens Internetanslutning med en eller flera datorer eller enheter +USB bağlantısı
+Telefonunuzun internet bağlantısını bilgisayarınızla paylaşmak için telefonunuzu bir USB kablosuyla bilgisayarınıza bağlayabilirsiniz +Kablosuz bağlantı
+Telefonunuzun internet bağlantısını bir veya daha fazla bilgisayarla ya da diğer cihazlarla paylaşmak için telefonunuzu kablosuz erişim noktasına dönüştürebilirsiniz +USB bağlantısı
+Telefonunuzun internet bağlantısını bilgisayarınızla paylaşmak için telefonunuzu bir USB kablosuyla bilgisayarınıza bağlayabilirsiniz +Kablosuz bağlantı
+Telefonunuzun internet bağlantısını bir veya daha fazla bilgisayarla ya da diğer cihazlarla paylaşmak için telefonunuzu kablosuz erişim noktasına dönüştürebilirsiniz +USB 绑定
+您可以通过 USB 线将手机与计算机绑定,从而与计算机共享手机的互联网连接 +Wi-Fi 绑定
+您可以将手机设为 Wi-Fi 接入点,从而与一台或多台计算机或者其他设备共享手机的互联网连接 +USB 绑定
+您可以通过 USB 线将手机与计算机绑定,从而与计算机共享手机的互联网连接 +Wi-Fi 绑定
+您可以将手机设为 Wi-Fi 接入点,从而与一台或多台计算机或者其他设备共享手机的互联网连接 +USB 數據連線
+您可以使用 USB 纜線讓手機和電腦連線,使電腦可以共用手機的網際網路連線 +Wi-Fi 數據連線
+您可以將手機變成 Wi-Fi 存取點,讓一或多台電腦或其他裝置可以共用手機的網際網路連線 +USB 數據連線
+您可以使用 USB 纜線讓手機和電腦連線,使電腦可以共用手機的網際網路連線 +Wi-Fi 數據連線
+您可以將手機變成 Wi-Fi 存取點,讓一或多台電腦或其他裝置可以共用手機的網際網路連線 ++ * $ adb shell pm enable com.android.settings/.CryptKeeper + * $ adb shell am start \ + * -e "com.android.settings.CryptKeeper.DEBUG_FORCE_VIEW" "progress" \ + * -n com.android.settings/.CryptKeeper + *+ */ +public class CryptKeeper extends Activity implements TextView.OnEditorActionListener { + private static final String TAG = "CryptKeeper"; + + private static final String DECRYPT_STATE = "trigger_restart_framework"; + + private static final int UPDATE_PROGRESS = 1; + private static final int COOLDOWN = 2; + + private static final int MAX_FAILED_ATTEMPTS = 30; + private static final int COOL_DOWN_ATTEMPTS = 10; + private static final int COOL_DOWN_INTERVAL = 30; // 30 seconds + + // Intent action for launching the Emergency Dialer activity. + static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL"; + + // Debug Intent extras so that this Activity may be started via adb for debugging UI layouts + private static final String EXTRA_FORCE_VIEW = + "com.android.settings.CryptKeeper.DEBUG_FORCE_VIEW"; + private static final String FORCE_VIEW_PROGRESS = "progress"; + private static final String FORCE_VIEW_ENTRY = "entry"; + private static final String FORCE_VIEW_ERROR = "error"; + + /** When encryption is detected, this flag indivates whether or not we've checked for erros. */ + private boolean mValidationComplete; + private boolean mValidationRequested; + /** A flag to indicate that the volume is in a bad state (e.g. partially encrypted). */ + private boolean mEncryptionGoneBad; + + private int mCooldown; + PowerManager.WakeLock mWakeLock; + private EditText mPasswordEntry; + + /** + * Used to propagate state through configuration changes (e.g. screen rotation) + */ + private static class NonConfigurationInstanceState { + final PowerManager.WakeLock wakelock; + + NonConfigurationInstanceState(PowerManager.WakeLock _wakelock) { + wakelock = _wakelock; + } + } + + // This activity is used to fade the screen to black after the password is entered. + public static class Blank extends Activity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.crypt_keeper_blank); + } + } + + private class DecryptTask extends AsyncTask
Reinflating views from resources is expensive and prevents us from
* caching widget pointers, so we use a single-inflate pattern: we lazy-
* inflate each view, caching all of the widget pointers we'll need at the
@@ -169,37 +128,115 @@ private void establishFinalConfirmationState() {
* to change contents.
*/
private void establishInitialState() {
- if (mInitialView == null) {
- mInitialView = mInflater.inflate(R.layout.master_clear_primary, null);
- mInitiateButton =
- (Button) mInitialView.findViewById(R.id.initiate_master_clear);
- mInitiateButton.setOnClickListener(mInitiateListener);
+ mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_master_clear);
+ mInitiateButton.setOnClickListener(mInitiateListener);
+ mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
+ mExternalStorage = (CheckBox) mContentView.findViewById(R.id.erase_external);
+
+ /*
+ * If the external storage is emulated, it will be erased with a factory
+ * reset at any rate. There is no need to have a separate option until
+ * we have a factory reset that only erases some directories and not
+ * others. Likewise, if it's non-removable storage, it could potentially have been
+ * encrypted, and will also need to be wiped.
+ */
+ boolean isExtStorageEmulated = Environment.isExternalStorageEmulated();
+ if (isExtStorageEmulated
+ || (!Environment.isExternalStorageRemovable() && isExtStorageEncrypted())) {
+ mExternalStorageContainer.setVisibility(View.GONE);
+
+ final View externalOption = mContentView.findViewById(R.id.erase_external_option_text);
+ externalOption.setVisibility(View.GONE);
+
+ final View externalAlsoErased = mContentView.findViewById(R.id.also_erases_external);
+ externalAlsoErased.setVisibility(View.VISIBLE);
+
+ // If it's not emulated, it is on a separate partition but it means we're doing
+ // a force wipe due to encryption.
+ mExternalStorage.setChecked(!isExtStorageEmulated);
+ } else {
+ mExternalStorageContainer.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ mExternalStorage.toggle();
+ }
+ });
}
- setContentView(mInitialView);
+ loadAccountList();
}
- @Override
- protected void onCreate(Bundle savedState) {
- super.onCreate(savedState);
+ private boolean isExtStorageEncrypted() {
+ String state = SystemProperties.get("vold.decrypt");
+ return !"".equals(state);
+ }
- mInitialView = null;
- mFinalView = null;
- mInflater = LayoutInflater.from(this);
- mLockUtils = new LockPatternUtils(getContentResolver());
+ private void loadAccountList() {
+ View accountsLabel = mContentView.findViewById(R.id.accounts_label);
+ LinearLayout contents = (LinearLayout)mContentView.findViewById(R.id.accounts);
+ contents.removeAllViews();
- establishInitialState();
+ Context context = getActivity();
+
+ AccountManager mgr = AccountManager.get(context);
+ Account[] accounts = mgr.getAccounts();
+ final int N = accounts.length;
+ if (N == 0) {
+ accountsLabel.setVisibility(View.GONE);
+ contents.setVisibility(View.GONE);
+ return;
+ }
+
+ LayoutInflater inflater = (LayoutInflater)context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+
+ AuthenticatorDescription[] descs = AccountManager.get(context).getAuthenticatorTypes();
+ final int M = descs.length;
+
+ for (int i=0; i
- * Intent intent = new Intent();
- * intent.setClassName("com.android.browser.ProxySelector");
- * startActivity(intent);
- *
- *
- * you can add extra options to the intent by using
- *
- *
- * intent.putExtra(key, value);
- *
- *
- * the extra options are:
- *
- * button-label: a string label to display for the okay button
- * title: the title of the window
- * error-text: If not null, will be used as the label of the error message.
- */
-public class ProxySelector extends Activity
-{
- private final static String LOGTAG = "Settings";
+public class ProxySelector extends Fragment implements DialogCreatable {
+ private static final String TAG = "ProxySelector";
EditText mHostnameField;
EditText mPortField;
+ EditText mExclusionListField;
Button mOKButton;
+ Button mClearButton;
+ Button mDefaultButton;
// Matches blank input, ips, and domain names
- private static final String HOSTNAME_REGEXP = "^$|^[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*$";
+ private static final String HOSTNAME_REGEXP =
+ "^$|^[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*$";
private static final Pattern HOSTNAME_PATTERN;
+ private static final String EXCLUSION_REGEXP =
+ "$|^(.?[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*)+$";
+ private static final Pattern EXCLUSION_PATTERN;
static {
HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP);
+ EXCLUSION_PATTERN = Pattern.compile(EXCLUSION_REGEXP);
}
+ private static final int ERROR_DIALOG_ID = 0;
+
+ private SettingsDialogFragment mDialogFragment;
+ private View mView;
+ @Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ }
- if (android.util.Config.LOGV) Log.v(LOGTAG, "[ProxySelector] onStart");
-
- setContentView(R.layout.proxy);
- initView();
- populateFields(false);
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mView = inflater.inflate(R.layout.proxy, container, false);
+ initView(mView);
+ // TODO: Populate based on connection status
+ populateFields();
+ return mView;
}
- protected void showError(int error) {
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final DevicePolicyManager dpm =
+ (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
+
+ final boolean userSetGlobalProxy = (dpm.getGlobalProxyAdmin() == null);
+ // Disable UI if the Global Proxy is being controlled by a Device Admin
+ mHostnameField.setEnabled(userSetGlobalProxy);
+ mPortField.setEnabled(userSetGlobalProxy);
+ mExclusionListField.setEnabled(userSetGlobalProxy);
+ mOKButton.setEnabled(userSetGlobalProxy);
+ mClearButton.setEnabled(userSetGlobalProxy);
+ mDefaultButton.setEnabled(userSetGlobalProxy);
+ }
- new AlertDialog.Builder(this)
- .setTitle(R.string.proxy_error)
- .setMessage(error)
- .setPositiveButton(R.string.proxy_error_dismiss, null)
- .show();
+ // Dialog management
+
+ @Override
+ public Dialog onCreateDialog(int id) {
+ if (id == ERROR_DIALOG_ID) {
+ String hostname = mHostnameField.getText().toString().trim();
+ String portStr = mPortField.getText().toString().trim();
+ String exclList = mExclusionListField.getText().toString().trim();
+ String msg = getActivity().getString(validate(hostname, portStr, exclList));
+
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.proxy_error)
+ .setPositiveButton(R.string.proxy_error_dismiss, null)
+ .setMessage(msg)
+ .create();
+ }
+ return null;
}
- void initView() {
+ private void showDialog(int dialogId) {
+ if (mDialogFragment != null) {
+ Log.e(TAG, "Old dialog fragment not null!");
+ }
+ mDialogFragment = new SettingsDialogFragment(this, dialogId);
+ mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
+ }
- mHostnameField = (EditText)findViewById(R.id.hostname);
+ private void initView(View view) {
+ mHostnameField = (EditText)view.findViewById(R.id.hostname);
mHostnameField.setOnFocusChangeListener(mOnFocusChangeHandler);
- mPortField = (EditText)findViewById(R.id.port);
+ mPortField = (EditText)view.findViewById(R.id.port);
mPortField.setOnClickListener(mOKHandler);
mPortField.setOnFocusChangeListener(mOnFocusChangeHandler);
- mOKButton = (Button)findViewById(R.id.action);
+ mExclusionListField = (EditText)view.findViewById(R.id.exclusionlist);
+ mExclusionListField.setOnFocusChangeListener(mOnFocusChangeHandler);
+
+ mOKButton = (Button)view.findViewById(R.id.action);
mOKButton.setOnClickListener(mOKHandler);
- Button b = (Button)findViewById(R.id.clear);
- b.setOnClickListener(mClearHandler);
+ mClearButton = (Button)view.findViewById(R.id.clear);
+ mClearButton.setOnClickListener(mClearHandler);
- b = (Button)findViewById(R.id.defaultView);
- b.setOnClickListener(mDefaultHandler);
+ mDefaultButton = (Button)view.findViewById(R.id.defaultView);
+ mDefaultButton.setOnClickListener(mDefaultHandler);
}
- void populateFields(boolean useDefault) {
- String hostname = null;
+ void populateFields() {
+ final Activity activity = getActivity();
+ String hostname = "";
int port = -1;
- if (useDefault) {
- // Use the default proxy settings provided by the carrier
- hostname = Proxy.getDefaultHost();
- port = Proxy.getDefaultPort();
- } else {
- // Use the last setting given by the user
- hostname = Proxy.getHost(this);
- port = Proxy.getPort(this);
+ String exclList = "";
+ // Use the last setting given by the user
+ ConnectivityManager cm =
+ (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ ProxyProperties proxy = cm.getGlobalProxy();
+ if (proxy != null) {
+ hostname = proxy.getHost();
+ port = proxy.getPort();
+ exclList = proxy.getExclusionList();
}
if (hostname == null) {
@@ -134,7 +179,9 @@ void populateFields(boolean useDefault) {
String portStr = port == -1 ? "" : Integer.toString(port);
mPortField.setText(portStr);
- Intent intent = getIntent();
+ mExclusionListField.setText(exclList);
+
+ final Intent intent = activity.getIntent();
String buttonLabel = intent.getStringExtra("button-label");
if (!TextUtils.isEmpty(buttonLabel)) {
@@ -143,7 +190,7 @@ void populateFields(boolean useDefault) {
String title = intent.getStringExtra("title");
if (!TextUtils.isEmpty(title)) {
- setTitle(title);
+ activity.setTitle(title);
}
}
@@ -151,11 +198,17 @@ void populateFields(boolean useDefault) {
* validate syntax of hostname and port entries
* @return 0 on success, string resource ID on failure
*/
- int validate(String hostname, String port) {
+ public static int validate(String hostname, String port, String exclList) {
Matcher match = HOSTNAME_PATTERN.matcher(hostname);
+ String exclListArray[] = exclList.split(",");
if (!match.matches()) return R.string.proxy_error_invalid_host;
+ for (String excl : exclListArray) {
+ Matcher m = EXCLUSION_PATTERN.matcher(excl);
+ if (!m.matches()) return R.string.proxy_error_invalid_exclusion_list;
+ }
+
if (hostname.length() > 0 && port.length() == 0) {
return R.string.proxy_error_empty_port;
}
@@ -184,11 +237,12 @@ boolean saveToDb() {
String hostname = mHostnameField.getText().toString().trim();
String portStr = mPortField.getText().toString().trim();
- int port = -1;
+ String exclList = mExclusionListField.getText().toString().trim();
+ int port = 0;
- int result = validate(hostname, portStr);
+ int result = validate(hostname, portStr, exclList);
if (result > 0) {
- showError(result);
+ showDialog(ERROR_DIALOG_ID);
return false;
}
@@ -196,42 +250,28 @@ boolean saveToDb() {
try {
port = Integer.parseInt(portStr);
} catch (NumberFormatException ex) {
+ // should never happen - caught by validate above
return false;
}
}
-
+ ProxyProperties p = new ProxyProperties(hostname, port, exclList);
// FIXME: The best solution would be to make a better UI that would
// disable editing of the text boxes if the user chooses to use the
// default settings. i.e. checking a box to always use the default
// carrier. http:/b/issue?id=756480
- // FIXME: This currently will not work if the default host is blank and
- // the user has cleared the input boxes in order to not use a proxy.
- // This is a UI problem and can be solved with some better form
- // controls.
// FIXME: If the user types in a proxy that matches the default, should
// we keep that setting? Can be fixed with a new UI.
- ContentResolver res = getContentResolver();
- if (hostname.equals(Proxy.getDefaultHost())
- && port == Proxy.getDefaultPort()) {
- // If the user hit the default button and didn't change any of
- // the input boxes, treat it as if the user has not specified a
- // proxy.
- hostname = null;
- }
-
- if (!TextUtils.isEmpty(hostname)) {
- hostname += ':' + portStr;
- }
- Settings.Secure.putString(res, Settings.Secure.HTTP_PROXY, hostname);
- sendBroadcast(new Intent(Proxy.PROXY_CHANGE_ACTION));
+ ConnectivityManager cm =
+ (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+ cm.setGlobalProxy(p);
return true;
}
OnClickListener mOKHandler = new OnClickListener() {
public void onClick(View v) {
if (saveToDb()) {
- finish();
+ getActivity().onBackPressed();
}
}
};
@@ -240,12 +280,14 @@ public void onClick(View v) {
public void onClick(View v) {
mHostnameField.setText("");
mPortField.setText("");
+ mExclusionListField.setText("");
}
};
OnClickListener mDefaultHandler = new OnClickListener() {
public void onClick(View v) {
- populateFields(true);
+ // TODO: populate based on connection status
+ populateFields();
}
};
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index 257122bbdf6..2055af01ef1 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -17,26 +17,28 @@
package com.android.settings;
import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.DialogInterface;
+import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.TrafficStats;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
-import android.os.INetStatService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.preference.PreferenceManager;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.NeighboringCellInfo;
+import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;
import android.text.format.DateUtils;
import android.util.Log;
@@ -51,28 +53,29 @@
import android.widget.TextView;
import android.widget.EditText;
+import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.PhoneStateIntentReceiver;
import com.android.internal.telephony.TelephonyProperties;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.PdpConnection;
+import com.android.internal.telephony.gsm.GsmDataConnection;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
+import android.util.Log;
+
public class RadioInfo extends Activity {
private final String TAG = "phone";
-
+
private static final int EVENT_PHONE_STATE_CHANGED = 100;
private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
private static final int EVENT_SERVICE_STATE_CHANGED = 300;
@@ -81,8 +84,6 @@ public class RadioInfo extends Activity {
private static final int EVENT_QUERY_PREFERRED_TYPE_DONE = 1000;
private static final int EVENT_SET_PREFERRED_TYPE_DONE = 1001;
private static final int EVENT_QUERY_NEIGHBORING_CIDS_DONE = 1002;
- private static final int EVENT_SET_QXDMLOG_DONE = 1003;
- private static final int EVENT_SET_CIPHER_DONE = 1004;
private static final int EVENT_QUERY_SMSC_DONE = 1005;
private static final int EVENT_UPDATE_SMSC_DONE = 1006;
@@ -92,7 +93,9 @@ public class RadioInfo extends Activity {
private static final int MENU_ITEM_VIEW_SDN = 3;
private static final int MENU_ITEM_GET_PDP_LIST = 4;
private static final int MENU_ITEM_TOGGLE_DATA = 5;
- private static final int MENU_ITEM_TOGGLE_DATA_ON_BOOT = 6;
+
+ static final String ENABLE_DATA_STR = "Enable data connection";
+ static final String DISABLE_DATA_STR = "Disable data connection";
private TextView mDeviceId; //DeviceId is the IMEI in GSM and the MEID in CDMA
private TextView number;
@@ -117,27 +120,19 @@ public class RadioInfo extends Activity {
private TextView mPingIpAddr;
private TextView mPingHostname;
private TextView mHttpClientTest;
- private TextView cipherState;
private TextView dnsCheckState;
private EditText smsc;
private Button radioPowerButton;
- private Button qxdmLogButton;
- private Button cipherToggleButton;
private Button dnsCheckToggleButton;
private Button pingTestButton;
private Button updateSmscButton;
private Button refreshSmscButton;
+ private Button oemInfoButton;
private Spinner preferredNetworkType;
private TelephonyManager mTelephonyManager;
private Phone phone = null;
private PhoneStateIntentReceiver mPhoneStateReceiver;
- private INetStatService netstat;
-
- private OemCommands mOem = null;
- private boolean mQxdmLogEnabled;
- // The requested cipher state
- private boolean mCipherOn;
private String mPingIpAddrResult;
private String mPingHostnameResult;
@@ -198,9 +193,14 @@ public void handleMessage(Message msg) {
ar= (AsyncResult) msg.obj;
if (ar.exception == null) {
int type = ((int[])ar.result)[0];
+ if (type >= mPreferredNetworkLabels.length) {
+ Log.e(TAG, "[RadioInfo] EVENT_QUERY_PREFERRED_TYPE_DONE: unknown " +
+ "type=" + type);
+ type = mPreferredNetworkLabels.length - 1;
+ }
preferredNetworkType.setSelection(type, true);
} else {
- preferredNetworkType.setSelection(3, true);
+ preferredNetworkType.setSelection(mPreferredNetworkLabels.length - 1, true);
}
break;
case EVENT_SET_PREFERRED_TYPE_DONE:
@@ -218,22 +218,6 @@ public void handleMessage(Message msg) {
mNeighboringCids.setText("unknown");
}
break;
- case EVENT_SET_QXDMLOG_DONE:
- ar= (AsyncResult) msg.obj;
- if (ar.exception == null) {
- mQxdmLogEnabled = !mQxdmLogEnabled;
-
- updateQxdmState(mQxdmLogEnabled);
- displayQxdmEnableResult();
- }
- break;
- case EVENT_SET_CIPHER_DONE:
- ar= (AsyncResult) msg.obj;
- if (ar.exception == null) {
- setCiphPref(mCipherOn);
- }
- updateCiphState();
- break;
case EVENT_QUERY_SMSC_DONE:
ar= (AsyncResult) msg.obj;
if (ar.exception != null) {
@@ -256,116 +240,6 @@ public void handleMessage(Message msg) {
}
};
- private class OemCommands {
-
- public final int OEM_QXDM_SDLOG_DEFAULT_FILE_SIZE = 32;
- public final int OEM_QXDM_SDLOG_DEFAULT_MASK = 0;
- public final int OEM_QXDM_SDLOG_DEFAULT_MAX_INDEX = 8;
-
- final int SIZE_OF_INT = 4;
- final int OEM_FEATURE_ENABLE = 1;
- final int OEM_FEATURE_DISABLE = 0;
- final int OEM_SIMPE_FEAUTURE_LEN = 1;
-
- final int OEM_QXDM_SDLOG_FUNCTAG = 0x00010000;
- final int OEM_QXDM_SDLOG_LEN = 4;
- final int OEM_PS_AUTO_ATTACH_FUNCTAG = 0x00020000;
- final int OEM_CIPHERING_FUNCTAG = 0x00020001;
-
- /**
- * The OEM interface to store QXDM to SD.
- *
- * To start/stop logging QXDM logs to SD card, use tag
- * OEM_RIL_HOOK_QXDM_SD_LOG_SETUP 0x00010000
- *
- * "data" is a const oem_ril_hook_qxdm_sdlog_setup_data_st *
- * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->head.func_tag
- * should be OEM_RIL_HOOK_QXDM_SD_LOG_SETUP
- * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->head.len
- * should be "sizeof(unsigned int) * 4"
- * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->mode
- * could be 0 for 'stop logging', or 1 for 'start logging'
- * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_file_size
- * will assign the size of each log file, and it could be a value between
- * 1 and 512 (in megabytes, default value is recommended to set as 32).
- * This value will be ignored when mode == 0.
- * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_mask will
- * assign the rule to filter logs, and it is a bitmask (bit0 is for MsgAll,
- * bit1 is for LogAll, and bit2 is for EventAll) recommended to be set as 0
- * by default. This value will be ignored when mode == 0.
- * ((const oem_ril_hook_qxdm_sdlog_setup_data_st *)data)->log_max_fileindex
- * set the how many logfiles will storted before roll over. This value will
- * be ignored when mode == 0.
- *
- * "response" is NULL
- *
- * typedef struct _oem_ril_hook_raw_head_st {
- * unsigned int func_tag;
- * unsigned int len;
- * } oem_ril_hook_raw_head_st;
- *
- * typedef struct _oem_ril_hook_qxdm_sdlog_setup_data_st {
- * oem_ril_hook_raw_head_st head;
- * unsigned int mode;
- * unsigned int log_file_size;
- * unsigned int log_mask;
- * unsigned int log_max_fileindex;
- * } oem_ril_hook_qxdm_sdlog_setup_data_st;
- *
- * @param enable set true to start logging QXDM in SD card
- * @param fileSize is the log file size in MB
- * @param mask is the log mask to filter
- * @param maxIndex is the maximum roll-over file number
- * @return byteArray to use in RIL RAW command
- */
- byte[] getQxdmSdlogData(boolean enable, int fileSize, int mask, int maxIndex) {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(bos);
- try {
- writeIntLittleEndian(dos, OEM_QXDM_SDLOG_FUNCTAG);
- writeIntLittleEndian(dos, OEM_QXDM_SDLOG_LEN * SIZE_OF_INT);
- writeIntLittleEndian(dos, enable ?
- OEM_FEATURE_ENABLE : OEM_FEATURE_DISABLE);
- writeIntLittleEndian(dos, fileSize);
- writeIntLittleEndian(dos, mask);
- writeIntLittleEndian(dos, maxIndex);
- } catch (IOException e) {
- return null;
- }
- return bos.toByteArray();
- }
-
- byte[] getPsAutoAttachData(boolean enable) {
- return getSimpleFeatureData(OEM_PS_AUTO_ATTACH_FUNCTAG, enable);
- }
-
- byte[] getCipheringData(boolean enable) {
- return getSimpleFeatureData(OEM_CIPHERING_FUNCTAG, enable);
- }
-
- private byte[] getSimpleFeatureData(int tag, boolean enable) {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(bos);
- try {
- writeIntLittleEndian(dos, tag);
- writeIntLittleEndian(dos, OEM_SIMPE_FEAUTURE_LEN * SIZE_OF_INT);
- writeIntLittleEndian(dos, enable ?
- OEM_FEATURE_ENABLE : OEM_FEATURE_DISABLE);
- } catch (IOException e) {
- return null;
- }
- return bos.toByteArray();
- }
-
- private void writeIntLittleEndian(DataOutputStream dos, int val)
- throws IOException {
- dos.writeByte(val);
- dos.writeByte(val >> 8);
- dos.writeByte(val >> 16);
- dos.writeByte(val >> 24);
- }
- }
-
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -396,7 +270,6 @@ public void onCreate(Bundle icicle) {
sentSinceReceived = (TextView) findViewById(R.id.sentSinceReceived);
sent = (TextView) findViewById(R.id.sent);
received = (TextView) findViewById(R.id.received);
- cipherState = (TextView) findViewById(R.id.ciphState);
smsc = (EditText) findViewById(R.id.smsc);
dnsCheckState = (TextView) findViewById(R.id.dnsCheckState);
@@ -407,18 +280,22 @@ public void onCreate(Bundle icicle) {
preferredNetworkType = (Spinner) findViewById(R.id.preferredNetworkType);
ArrayAdapter
");
- }
- mDescription = sb.toString();
- }
+ public boolean onPreferenceChange(Preference preference, Object value) {
+ return true;
}
}
diff --git a/src/com/android/settings/SetFullBackupPassword.java b/src/com/android/settings/SetFullBackupPassword.java
new file mode 100644
index 00000000000..9f3f29f4452
--- /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 4f888ff2375..78e680e89fd 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -16,33 +16,613 @@
package com.android.settings;
+import com.android.settings.accounts.AccountSyncSettings;
+import com.android.settings.bluetooth.BluetoothEnabler;
+import com.android.settings.fuelgauge.PowerUsageSummary;
+import com.android.settings.wifi.WifiEnabler;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
import android.os.Bundle;
+import android.preference.Preference;
import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
-import android.provider.Settings.System;
+import android.preference.PreferenceFragment;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.Switch;
+import android.widget.TextView;
-public class Settings extends PreferenceActivity {
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Top-level settings activity to handle single pane and double pane UI layout.
+ */
+public class Settings extends PreferenceActivity implements ButtonBarHandler {
+
+ private static final String LOG_TAG = "Settings";
+ private static final String META_DATA_KEY_HEADER_ID =
+ "com.android.settings.TOP_LEVEL_HEADER_ID";
+ private static final String META_DATA_KEY_FRAGMENT_CLASS =
+ "com.android.settings.FRAGMENT_CLASS";
+ private static final String META_DATA_KEY_PARENT_TITLE =
+ "com.android.settings.PARENT_FRAGMENT_TITLE";
+ private static final String META_DATA_KEY_PARENT_FRAGMENT_CLASS =
+ "com.android.settings.PARENT_FRAGMENT_CLASS";
+
+ private static final String EXTRA_CLEAR_UI_OPTIONS = "settings:remove_ui_options";
+
+ private static final String SAVE_KEY_CURRENT_HEADER = "com.android.settings.CURRENT_HEADER";
+ private static final String SAVE_KEY_PARENT_HEADER = "com.android.settings.PARENT_HEADER";
+
+ private String mFragmentClass;
+ private int mTopLevelHeaderId;
+ private Header mFirstHeader;
+ private Header mCurrentHeader;
+ private Header mParentHeader;
+ private boolean mInLocalHeaderSwitch;
+
+ // TODO: Update Call Settings based on airplane mode state.
+
+ protected HashMap