diff --git a/AndroidManifest.xml b/AndroidManifest.xml index eb2ae6aaa86..b7978aae58f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -14,7 +14,7 @@ - + diff --git a/res/layout/manage_applications.xml b/res/layout/manage_applications.xml index 078322ace63..95d48479ec5 100755 --- a/res/layout/manage_applications.xml +++ b/res/layout/manage_applications.xml @@ -43,9 +43,11 @@ android:layout_height="wrap_content" android:layout_marginTop="-5dp" android:orientation="horizontal" + android:clipChildren="false" + android:clipToPadding="false" android:paddingTop="30dp" - android:paddingLeft="2dp" - android:paddingRight="2dp" + android:paddingLeft="4dp" + android:paddingRight="4dp" android:paddingBottom="1dp"> diff --git a/res/layout/running_processes_view.xml b/res/layout/running_processes_view.xml index 9f01eda3cf3..3558e92b233 100644 --- a/res/layout/running_processes_view.xml +++ b/res/layout/running_processes_view.xml @@ -41,9 +41,11 @@ android:layout_height="wrap_content" android:layout_marginTop="-5dp" android:orientation="horizontal" + android:clipChildren="false" + android:clipToPadding="false" android:paddingTop="30dp" - android:paddingLeft="2dp" - android:paddingRight="2dp" + android:paddingLeft="4dp" + android:paddingRight="4dp" android:paddingBottom="1dp"> diff --git a/res/values/strings.xml b/res/values/strings.xml index e00d3c21b83..1d763eede4e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1406,12 +1406,14 @@ Insert USB storage for mounting Insert an SD card for mounting - - Mount shared storage + + + Mount USB storage Mount SD card - - Mount the internal USB storage + + + Mount the USB storage Mount the SD card @@ -1678,6 +1680,12 @@ Use server to assist GPS (uncheck to reduce network usage) Use server to assist GPS (uncheck to improve GPS performance) + + Use location for Google search + + Use location for Google search and other Google services + + Location used to improve Google search results and other Google services diff --git a/src/com/android/settings/GoogleLocationSettingHelper.java b/src/com/android/settings/GoogleLocationSettingHelper.java new file mode 100644 index 00000000000..0d4861e36e5 --- /dev/null +++ b/src/com/android/settings/GoogleLocationSettingHelper.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2010 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.content.ActivityNotFoundException; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +/** + * Helper class to read and write the 'Use My Location' setting used by Google Apps (e.g. GoogleQSB, + * VoiceSearch). + * + * This class duplicates a small amount of functionality from GSF (Google Services Framework) to + * allow the open source Settings app to interface to the 'Use My Location' setting owned by GSF. + */ +public class GoogleLocationSettingHelper { + + private static final String TAG = "GoogleLocationSettingHelper"; + + /** + * User has disagreed to use location for Google services. + */ + public static final int USE_LOCATION_FOR_SERVICES_OFF = 0; + + /** + * User has agreed to use location for Google services. + */ + public static final int USE_LOCATION_FOR_SERVICES_ON = 1; + + /** + * The user has neither agreed nor disagreed to use location for Google services yet. + */ + public static final int USE_LOCATION_FOR_SERVICES_NOT_SET = 2; + + private static final String GOOGLE_SETTINGS_AUTHORITY = "com.google.settings"; + private static final Uri GOOGLE_SETTINGS_CONTENT_URI = + Uri.parse("content://" + GOOGLE_SETTINGS_AUTHORITY + "/partner"); + private static final String NAME = "name"; + private static final String VALUE = "value"; + private static final String USE_LOCATION_FOR_SERVICES = "use_location_for_services"; + + private static final String ACTION_SET_USE_LOCATION_FOR_SERVICES = + "com.google.android.gsf.action.SET_USE_LOCATION_FOR_SERVICES"; + public static final String EXTRA_DISABLE_USE_LOCATION_FOR_SERVICES = "disable"; + + /** + * Determine if the 'Use My Location' setting is applicable on this device, i.e. if the + * activity used to enabled/disable it is present. + */ + public static boolean isAvailable(Context context) { + ResolveInfo ri = context.getPackageManager().resolveActivity(getSetUseLocationIntent(), + PackageManager.MATCH_DEFAULT_ONLY); + return ri != null; + } + + private static Intent getSetUseLocationIntent() { + Intent i = new Intent(ACTION_SET_USE_LOCATION_FOR_SERVICES); + return i; + } + + /** + * Get the current value for the 'Use value for location' setting. + * @return One of {@link #USE_LOCATION_FOR_SERVICES_NOT_SET}, + * {@link #USE_LOCATION_FOR_SERVICES_OFF} or {@link #USE_LOCATION_FOR_SERVICES_ON}. + */ + public static int getUseLocationForServices(Context context) { + ContentResolver resolver = context.getContentResolver(); + Cursor c = null; + String stringValue = null; + try { + c = resolver.query(GOOGLE_SETTINGS_CONTENT_URI, new String[] { VALUE }, NAME + "=?", + new String[] { USE_LOCATION_FOR_SERVICES }, null); + if (c != null && c.moveToNext()) { + stringValue = c.getString(0); + } + } catch (RuntimeException e) { + Log.w(TAG, "Failed to get 'Use My Location' setting", e); + } finally { + if (c != null) { + c.close(); + } + } + if (stringValue == null) { + return USE_LOCATION_FOR_SERVICES_NOT_SET; + } + int value; + try { + value = Integer.parseInt(stringValue); + } catch (NumberFormatException nfe) { + value = USE_LOCATION_FOR_SERVICES_NOT_SET; + } + return value; + } + + /** + * Change the value of the 'Use My Location' setting. This launches a GSF activity which has + * the permissions to actually make the change, prompting the user if necessary. + */ + public static void setUseLocationForServices(Context context, boolean use) { + Intent i = getSetUseLocationIntent(); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + i.putExtra(EXTRA_DISABLE_USE_LOCATION_FOR_SERVICES, !use); + try { + context.startActivity(i); + } catch (ActivityNotFoundException e) { + } + } + +} diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index dacc19f4337..dd512952c0a 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -36,10 +36,11 @@ import android.os.SystemProperties; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceCategory; +import android.preference.PreferenceGroup; import android.preference.PreferenceManager; import android.preference.PreferenceScreen; -import android.preference.Preference.OnPreferenceChangeListener; import android.provider.Settings; import android.security.Credentials; import android.security.KeyStore; @@ -78,15 +79,17 @@ public class SecuritySettings extends SettingsPreferenceFragment private CheckBoxPreference mShowPassword; // Location Settings + private static final String LOCATION_CATEGORY = "location_category"; private static final String LOCATION_NETWORK = "location_network"; private static final String LOCATION_GPS = "location_gps"; private static final String ASSISTED_GPS = "assisted_gps"; + private static final String USE_LOCATION = "location_use_for_services"; private static final String LOCK_AFTER_TIMEOUT_KEY = "lock_after_timeout"; private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123; private static final int FALLBACK_LOCK_AFTER_TIMEOUT_VALUE = 5000; // compatible with pre-Froyo // Credential storage - private CredentialStorage mCredentialStorage = new CredentialStorage(); + private final CredentialStorage mCredentialStorage = new CredentialStorage(); // Encrypted file system private CheckBoxPreference mEncryptedFSEnabled; @@ -94,6 +97,7 @@ public class SecuritySettings extends SettingsPreferenceFragment private CheckBoxPreference mNetwork; private CheckBoxPreference mGps; private CheckBoxPreference mAssistedGps; + private CheckBoxPreference mUseLocation; DevicePolicyManager mDPM; @@ -158,6 +162,22 @@ public class SecuritySettings extends SettingsPreferenceFragment mNetwork = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_NETWORK); mGps = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_GPS); mAssistedGps = (CheckBoxPreference) getPreferenceScreen().findPreference(ASSISTED_GPS); + if (GoogleLocationSettingHelper.isAvailable(getActivity())) { + // GSF present, Add setting for 'Use My Location' + PreferenceGroup locationCat = (PreferenceGroup) root.findPreference(LOCATION_CATEGORY); + CheckBoxPreference useLocation = new CheckBoxPreference(getActivity()); + useLocation.setKey(USE_LOCATION); + useLocation.setTitle(R.string.use_location_title); + useLocation.setSummaryOn(R.string.use_location_summary_enabled); + useLocation.setSummaryOff(R.string.use_location_summary_disabled); + useLocation.setChecked( + GoogleLocationSettingHelper.getUseLocationForServices(getActivity()) + == GoogleLocationSettingHelper.USE_LOCATION_FOR_SERVICES_ON); + useLocation.setPersistent(false); + useLocation.setOnPreferenceChangeListener(this); + locationCat.addPreference(useLocation); + mUseLocation = useLocation; + } PreferenceManager pm = getPreferenceManager(); @@ -398,7 +418,7 @@ public class SecuritySettings extends SettingsPreferenceFragment private static final int DLG_RESET = DLG_PASSWORD + 1; private static final int DLG_ENABLE_EFS = DLG_RESET + 1; - private KeyStore mKeyStore = KeyStore.getInstance(); + private final KeyStore mKeyStore = KeyStore.getInstance(); private int mState; private boolean mSubmit = false; private boolean mExternal = false; @@ -748,6 +768,14 @@ public class SecuritySettings extends SettingsPreferenceFragment } catch (NumberFormatException e) { Log.e("SecuritySettings", "could not persist lockAfter timeout setting", e); } + } else if (preference == mUseLocation) { + boolean newValue = value == null ? false : (Boolean) value; + GoogleLocationSettingHelper.setUseLocationForServices(getActivity(), newValue); + // We don't want to change the value immediately here, since the user may click + // disagree in the dialog that pops up. When the activity we just launched exits, this + // activity will be restated and the new value re-read, so the checkbox will get its + // new value then. + return false; } return true; } diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java index 95156249313..814bbbfa151 100644 --- a/src/com/android/settings/applications/ApplicationsState.java +++ b/src/com/android/settings/applications/ApplicationsState.java @@ -21,6 +21,7 @@ import android.os.SystemClock; import android.text.format.Formatter; import android.util.Log; +import java.io.File; import java.text.Collator; import java.text.Normalizer; import java.text.Normalizer.Form; @@ -66,14 +67,17 @@ public class ApplicationsState { } public static class AppEntry { - final String label; + final File apkFile; final long id; + String label; long size; long cacheSize; long codeSize; long dataSize; + boolean mounted; + String getNormalizedLabel() { if (normalizedLabel != null) { return normalizedLabel; @@ -92,12 +96,47 @@ public class ApplicationsState { String normalizedLabel; AppEntry(Context context, ApplicationInfo info, long id) { - CharSequence label = info.loadLabel(context.getPackageManager()); - this.label = label != null ? label.toString() : info.packageName; + apkFile = new File(info.sourceDir); this.id = id; this.info = info; this.size = SIZE_UNKNOWN; this.sizeStale = true; + ensureLabel(context); + } + + void ensureLabel(Context context) { + if (this.label == null || !this.mounted) { + if (!this.apkFile.exists()) { + this.mounted = false; + this.label = info.packageName; + } else { + this.mounted = true; + CharSequence label = info.loadLabel(context.getPackageManager()); + this.label = label != null ? label.toString() : info.packageName; + } + } + } + + boolean ensureIconLocked(Context context, PackageManager pm) { + if (this.icon == null) { + if (this.apkFile.exists()) { + this.icon = this.info.loadIcon(pm); + return true; + } else { + this.mounted = false; + this.icon = context.getResources().getDrawable( + com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon); + } + } else if (!this.mounted) { + // If the app wasn't mounted but is now mounted, reload + // its icon. + if (this.apkFile.exists()) { + this.mounted = true; + this.icon = this.info.loadIcon(pm); + return true; + } + } + return false; } } @@ -217,9 +256,11 @@ public class ApplicationsState { return; } boolean avail = Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(actionStr); - for (String pkgName : pkgList) { - if (avail) addPackage(pkgName); - else removePackage(pkgName); + if (avail) { + for (String pkgName : pkgList) { + removePackage(pkgName); + addPackage(pkgName); + } } } } @@ -312,6 +353,13 @@ public class ApplicationsState { for (int i=0; i=0; i--) { + sum += mAppEntries.get(i).cacheSize; + } + } + return sum; + } + int indexOfApplicationInfoLocked(String pkgName) { for (int i=mApplications.size()-1; i>=0; i--) { if (mApplications.get(i).packageName.equals(pkgName)) { @@ -528,7 +585,7 @@ public class ApplicationsState { private long getTotalSize(PackageStats ps) { if (ps != null) { - return ps.cacheSize+ps.codeSize+ps.dataSize; + return ps.codeSize+ps.dataSize; } return SIZE_INVALID; } @@ -630,16 +687,17 @@ public class ApplicationsState { synchronized (mEntriesMap) { for (int i=0; i parent, View view, int position, long id) { @@ -738,8 +751,8 @@ public class ManageApplications extends TabActivity implements for (int i=0; i LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile); CachedBluetoothDeviceManager cachedDeviceManager = mLocalManager.getCachedDeviceManager(); - Set devices = profileManager.getConnectedDevices(); + List devices = profileManager.getConnectedDevices(); if (devices == null) return; for (BluetoothDevice btDevice : devices) { CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(btDevice); diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java index d50332555e4..613ee258676 100644 --- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java +++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java @@ -196,10 +196,9 @@ public class LocalBluetoothManager { // If we are playing music, don't scan unless forced. if (mBluetoothA2dp != null) { - Set sinks = mBluetoothA2dp.getConnectedDevices(); + List sinks = mBluetoothA2dp.getConnectedDevices(); if (sinks.size() > 0) { - BluetoothDevice sink = sinks.toArray(new BluetoothDevice[sinks.size()])[0]; - if (mBluetoothA2dp.isA2dpPlaying(sink)) return; + if (mBluetoothA2dp.isA2dpPlaying(sinks.get(0))) return; } } } diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java index 7e11887a9b6..1480b163e4f 100644 --- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java +++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java @@ -197,7 +197,7 @@ public abstract class LocalBluetoothProfileManager { mLocalManager = localManager; } - public abstract Set getConnectedDevices(); + public abstract List getConnectedDevices(); public abstract boolean connect(BluetoothDevice device); @@ -261,7 +261,7 @@ public abstract class LocalBluetoothProfileManager { } @Override - public Set getConnectedDevices() { + public List getConnectedDevices() { return mService.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING, @@ -270,7 +270,7 @@ public abstract class LocalBluetoothProfileManager { @Override public boolean connect(BluetoothDevice device) { - Set sinks = getConnectedDevices(); + List sinks = getConnectedDevices(); if (sinks != null) { for (BluetoothDevice sink : sinks) { mService.disconnect(sink); @@ -378,14 +378,11 @@ public abstract class LocalBluetoothProfileManager { * We just bound to the service, so refresh the UI of the * headset device. */ - Set deviceSet = mService.getConnectedDevices(); - if (deviceSet.size() == 0) return; - - BluetoothDevice[] devices = - deviceSet.toArray(new BluetoothDevice[deviceSet.size()]); + List deviceList = mService.getConnectedDevices(); + if (deviceList.size() == 0) return; mLocalManager.getCachedDeviceManager() - .onProfileStateChanged(devices[0], Profile.HEADSET, + .onProfileStateChanged(deviceList.get(0), Profile.HEADSET, BluetoothProfile.STATE_CONNECTED); } }); @@ -415,7 +412,7 @@ public abstract class LocalBluetoothProfileManager { } @Override - public Set getConnectedDevices() { + public List getConnectedDevices() { return mService.getConnectedDevices(); } @@ -426,9 +423,8 @@ public abstract class LocalBluetoothProfileManager { @Override public boolean disconnect(BluetoothDevice device) { - Set deviceSet = getConnectedDevices(); - BluetoothDevice[] devices = deviceSet.toArray(new BluetoothDevice[deviceSet.size()]); - if (devices.length != 0 && devices[0].equals(device)) { + List deviceList = getConnectedDevices(); + if (deviceList.size() != 0 && deviceList.get(0).equals(device)) { // Downgrade prority as user is disconnecting the headset. if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) { mService.setPriority(device, BluetoothProfile.PRIORITY_ON); @@ -441,10 +437,9 @@ public abstract class LocalBluetoothProfileManager { @Override public int getConnectionStatus(BluetoothDevice device) { - Set deviceSet = getConnectedDevices(); - BluetoothDevice[] devices = deviceSet.toArray(new BluetoothDevice[deviceSet.size()]); + List deviceList = getConnectedDevices(); - return devices.length > 0 && devices[0].equals(device) + return deviceList.size() > 0 && deviceList.get(0).equals(device) ? convertState(mService.getConnectionState(device)) : SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED; } @@ -506,7 +501,7 @@ public abstract class LocalBluetoothProfileManager { } @Override - public Set getConnectedDevices() { + public List getConnectedDevices() { return null; } @@ -605,7 +600,7 @@ public abstract class LocalBluetoothProfileManager { } @Override - public Set getConnectedDevices() { + public List getConnectedDevices() { return mService.getConnectedInputDevices(); } @@ -703,7 +698,7 @@ public abstract class LocalBluetoothProfileManager { } @Override - public Set getConnectedDevices() { + public List getConnectedDevices() { return mService.getConnectedDevices(); } diff --git a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java index a74780d4432..23107da8f4f 100644 --- a/src/com/android/settings/fuelgauge/BatteryHistoryChart.java +++ b/src/com/android/settings/fuelgauge/BatteryHistoryChart.java @@ -59,7 +59,7 @@ public class BatteryHistoryChart extends View { void init(int width) { if (width > 0) { - mTicks = new int[width+2]; + mTicks = new int[width*2]; } else { mTicks = null; } @@ -68,7 +68,7 @@ public class BatteryHistoryChart extends View { } void addTick(int x, int bin) { - if (bin != mLastBin) { + if (bin != mLastBin && mNumTicks < mTicks.length) { mTicks[mNumTicks] = x | bin << CHART_DATA_BIN_SHIFT; mNumTicks++; mLastBin = bin; @@ -285,6 +285,8 @@ public class BatteryHistoryChart extends View { } } + a.recycle(); + mTextPaint.setColor(textColor.getDefaultColor()); mTextPaint.setTextSize(textSize); diff --git a/src/com/android/settings/nfc/NfcEnabler.java b/src/com/android/settings/nfc/NfcEnabler.java index 14e8b525f0d..c37c9bb7967 100644 --- a/src/com/android/settings/nfc/NfcEnabler.java +++ b/src/com/android/settings/nfc/NfcEnabler.java @@ -77,8 +77,7 @@ public class NfcEnabler implements Preference.OnPreferenceChangeListener { } mContext.registerReceiver(mReceiver, mIntentFilter); mCheckbox.setOnPreferenceChangeListener(this); - mNfcState = Settings.System.getInt(mContext.getContentResolver(), - Settings.System.NFC_ON, 0) != 0; + mNfcState = mNfcAdapter.isEnabled(); mCheckbox.setChecked(mNfcState); } @@ -103,9 +102,9 @@ public class NfcEnabler implements Preference.OnPreferenceChangeListener { Log.d(TAG, "Setting NFC enabled state to: " + desiredState); boolean success = false; if (desiredState) { - success = mNfcAdapter.enableTagDiscovery(); + success = mNfcAdapter.enable(); } else { - success = mNfcAdapter.disableTagDiscovery(); + success = mNfcAdapter.disable(); } if (success) { Log.d(TAG, "Successfully changed NFC enabled state to " + desiredState); diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 85e399d2cb0..30c2a3d6431 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -732,4 +732,8 @@ public class WifiSettings extends SettingsPreferenceFragment return 0; } } + + /* package */ void disableWifi() { + mWifiManager.setWifiEnabled(false); + } } diff --git a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java index 0ddd9da811a..ccdf9e97f34 100644 --- a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java +++ b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java @@ -19,11 +19,10 @@ package com.android.settings.wifi; import com.android.settings.R; import android.app.Activity; -import android.app.StatusBarManager; import android.content.Context; import android.net.NetworkInfo.DetailedState; import android.os.Bundle; -import android.util.Log; +import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; @@ -117,6 +116,11 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis mWifiSettings.onAddNetworkPressed(); break; case R.id.wifi_setup_skip_or_next: + if (TextUtils.equals(getString(R.string.wifi_setup_skip), ((Button)view).getText())) { + // We don't want to let Wifi enabled when a user press skip without choosing + // any access point. + mWifiSettings.disableWifi(); + } setResult(Activity.RESULT_OK); finish(); break;