summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/settings/DeviceInfoSettings.java15
-rw-r--r--src/com/android/settings/RegulatoryInfoDisplayActivity.java55
-rw-r--r--src/com/android/settings/Settings.java4
-rw-r--r--src/com/android/settings/UserDictionarySettings.java14
-rw-r--r--src/com/android/settings/applications/ProcStatsEntry.java214
-rw-r--r--src/com/android/settings/applications/ProcessStatsDetail.java258
-rw-r--r--src/com/android/settings/applications/ProcessStatsPreference.java8
-rw-r--r--src/com/android/settings/applications/ProcessStatsUi.java120
-rw-r--r--src/com/android/settings/fuelgauge/BatteryStatsHelper.java13
-rw-r--r--src/com/android/settings/fuelgauge/PowerUsageDetail.java3
-rw-r--r--src/com/android/settings/fuelgauge/PowerUsageSummary.java2
-rw-r--r--src/com/android/settings/location/LocationSettings.java21
-rw-r--r--src/com/android/settings/location/LocationSettingsBase.java29
-rw-r--r--src/com/android/settings/location/RecentLocationApps.java23
-rw-r--r--src/com/android/settings/location/SettingsInjector.java97
-rw-r--r--src/com/android/settings/nfc/PaymentBackend.java8
-rw-r--r--src/com/android/settings/nfc/PaymentDefaultDialog.java8
-rw-r--r--src/com/android/settings/nfc/PaymentSettings.java15
-rw-r--r--src/com/android/settings/tts/TextToSpeechSettings.java2
-rwxr-xr-xsrc/com/android/settings/wfd/WifiDisplaySettings.java37
-rw-r--r--src/com/android/settings/widget/SettingsAppWidgetProvider.java2
-rw-r--r--src/com/android/settings/wifi/AccessPoint.java7
-rw-r--r--src/com/android/settings/wifi/WifiDialog.java2
-rw-r--r--src/com/android/settings/wifi/WifiSettings.java33
-rw-r--r--src/com/android/settings/wifi/WifiSetupActivity.java22
-rw-r--r--src/com/android/settings/wifi/p2p/WifiP2pPeer.java7
26 files changed, 758 insertions, 261 deletions
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java
index ac74221..7e94741 100644
--- a/src/com/android/settings/DeviceInfoSettings.java
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -37,7 +37,7 @@ import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class DeviceInfoSettings extends SettingsPreferenceFragment {
+public class DeviceInfoSettings extends RestrictedSettingsFragment {
private static final String LOG_TAG = "DeviceInfoSettings";
@@ -70,12 +70,20 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment {
int mDevHitCountdown;
Toast mDevHitToast;
+ public DeviceInfoSettings() {
+ super(null /* Don't PIN protect the entire screen */);
+ }
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.device_info_settings);
+ // We only call ensurePinRestrictedPreference() when mDevHitCountdown == 0.
+ // This will keep us from entering developer mode without a PIN.
+ protectByRestrictions(KEY_BUILD_NUMBER);
+
setStringSummary(KEY_FIRMWARE_VERSION, Build.VERSION.RELEASE);
findPreference(KEY_FIRMWARE_VERSION).setEnabled(true);
setValueSummary(KEY_BASEBAND_VERSION, "gsm.version.baseband");
@@ -178,6 +186,11 @@ public class DeviceInfoSettings extends SettingsPreferenceFragment {
if (UserHandle.myUserId() != UserHandle.USER_OWNER) return true;
if (mDevHitCountdown > 0) {
+ if (mDevHitCountdown == 1) {
+ if (super.ensurePinRestrictedPreference(preference)) {
+ return true;
+ }
+ }
mDevHitCountdown--;
if (mDevHitCountdown == 0) {
getActivity().getSharedPreferences(DevelopmentSettings.PREF_FILE,
diff --git a/src/com/android/settings/RegulatoryInfoDisplayActivity.java b/src/com/android/settings/RegulatoryInfoDisplayActivity.java
index 8adecf1..171059c 100644
--- a/src/com/android/settings/RegulatoryInfoDisplayActivity.java
+++ b/src/com/android/settings/RegulatoryInfoDisplayActivity.java
@@ -22,7 +22,11 @@ import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.SystemProperties;
+import android.text.TextUtils;
import android.view.Gravity;
+import android.view.View;
+import android.widget.ImageView;
import android.widget.TextView;
/**
@@ -30,11 +34,14 @@ import android.widget.TextView;
* preference item, and when "*#07#" is dialed on the Phone keypad. To enable this feature,
* set the "config_show_regulatory_info" boolean to true in a device overlay resource, and in the
* same overlay, either add a drawable named "regulatory_info.png" containing a graphical version
- * of the required regulatory info, or add a string resource named "regulatory_info_text" with
- * an HTML version of the required information (text will be centered in the dialog).
+ * of the required regulatory info (If ro.bootloader.hardware.sku property is set use
+ * "regulatory_info_<sku>.png where sku is ro.bootloader.hardware.sku property value in lowercase"),
+ * or add a string resource named "regulatory_info_text" with an HTML version of the required
+ * information (text will be centered in the dialog).
*/
public class RegulatoryInfoDisplayActivity extends Activity implements
DialogInterface.OnDismissListener {
+ private final String REGULATORY_INFO_RESOURCE = "regulatory_info";
/**
* Display the regulatory info graphic in a dialog window.
@@ -52,21 +59,27 @@ public class RegulatoryInfoDisplayActivity extends Activity implements
.setTitle(R.string.regulatory_information)
.setOnDismissListener(this);
- boolean regulatoryInfoDrawableExists;
- try {
- Drawable d = resources.getDrawable(R.drawable.regulatory_info);
- // set to false if the width or height is <= 2
- // (missing PNG can return an empty 2x2 pixel Drawable)
- regulatoryInfoDrawableExists = (d.getIntrinsicWidth() > 2
- && d.getIntrinsicHeight() > 2);
- } catch (Resources.NotFoundException ignored) {
- regulatoryInfoDrawableExists = false;
+ boolean regulatoryInfoDrawableExists = false;
+ int resId = getResourceId();
+ if (resId != 0) {
+ try {
+ Drawable d = resources.getDrawable(resId);
+ // set to false if the width or height is <= 2
+ // (missing PNG can return an empty 2x2 pixel Drawable)
+ regulatoryInfoDrawableExists = (d.getIntrinsicWidth() > 2
+ && d.getIntrinsicHeight() > 2);
+ } catch (Resources.NotFoundException ignored) {
+ regulatoryInfoDrawableExists = false;
+ }
}
CharSequence regulatoryText = resources.getText(R.string.regulatory_info_text);
if (regulatoryInfoDrawableExists) {
- builder.setView(getLayoutInflater().inflate(R.layout.regulatory_info, null));
+ View view = getLayoutInflater().inflate(R.layout.regulatory_info, null);
+ ImageView image = (ImageView) view.findViewById(R.id.regulatoryInfo);
+ image.setImageResource(resId);
+ builder.setView(view);
builder.show();
} else if (regulatoryText.length() > 0) {
builder.setMessage(regulatoryText);
@@ -80,6 +93,24 @@ public class RegulatoryInfoDisplayActivity extends Activity implements
}
}
+ private int getResourceId() {
+ // Use regulatory_info by default.
+ int resId = getResources().getIdentifier(
+ REGULATORY_INFO_RESOURCE, "drawable", getPackageName());
+
+ // When hardware sku property exists, use regulatory_info_<sku> resource if valid.
+ String sku = SystemProperties.get("ro.boot.hardware.sku", "");
+ if (!TextUtils.isEmpty(sku)) {
+ String regulatory_info_res = REGULATORY_INFO_RESOURCE + "_" + sku.toLowerCase();
+ int id = getResources().getIdentifier(
+ regulatory_info_res, "drawable", getPackageName());
+ if (id != 0) {
+ resId = id;
+ }
+ }
+ return resId;
+ }
+
@Override
public void onDismiss(DialogInterface dialog) {
finish(); // close the activity
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 29945be..62d4aa8 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -66,6 +66,7 @@ import com.android.settings.deviceinfo.Memory;
import com.android.settings.deviceinfo.UsbSettings;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
+import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
import com.android.settings.inputmethod.SpellCheckersSettings;
import com.android.settings.inputmethod.UserDictionaryList;
import com.android.settings.location.LocationSettings;
@@ -332,7 +333,8 @@ public class Settings extends PreferenceActivity
ManageAccountsSettings.class.getName(),
PrintSettingsFragment.class.getName(),
TrustedCredentialsSettings.class.getName(),
- PaymentSettings.class.getName()
+ PaymentSettings.class.getName(),
+ KeyboardLayoutPickerFragment.class.getName()
};
@Override
diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java
index 9f6df50..da12004 100644
--- a/src/com/android/settings/UserDictionarySettings.java
+++ b/src/com/android/settings/UserDictionarySettings.java
@@ -16,6 +16,9 @@
package com.android.settings;
+import com.android.settings.inputmethod.UserDictionaryAddWordContents;
+import com.android.settings.inputmethod.UserDictionarySettingsUtils;
+
import android.app.ListFragment;
import android.content.ContentResolver;
import android.content.Context;
@@ -37,9 +40,6 @@ import android.widget.SectionIndexer;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
-import com.android.settings.inputmethod.UserDictionaryAddWordContents;
-import com.android.settings.inputmethod.UserDictionarySettingsUtils;
-
import java.util.Locale;
public class UserDictionarySettings extends ListFragment {
@@ -165,7 +165,7 @@ public class UserDictionarySettings extends ListFragment {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
MenuItem actionItem =
menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title)
- .setIcon(R.drawable.ic_menu_add);
+ .setIcon(R.drawable.ic_menu_add_dark);
actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
@@ -236,8 +236,9 @@ public class UserDictionarySettings extends ListFragment {
private AlphabetIndexer mIndexer;
- private ViewBinder mViewBinder = new ViewBinder() {
+ private final ViewBinder mViewBinder = new ViewBinder() {
+ @Override
public boolean setViewValue(View v, Cursor c, int columnIndex) {
if (columnIndex == INDEX_SHORTCUT) {
final String shortcut = c.getString(INDEX_SHORTCUT);
@@ -268,14 +269,17 @@ public class UserDictionarySettings extends ListFragment {
setViewBinder(mViewBinder);
}
+ @Override
public int getPositionForSection(int section) {
return null == mIndexer ? 0 : mIndexer.getPositionForSection(section);
}
+ @Override
public int getSectionForPosition(int position) {
return null == mIndexer ? 0 : mIndexer.getSectionForPosition(position);
}
+ @Override
public Object[] getSections() {
return null == mIndexer ? null : mIndexer.getSections();
}
diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java
index e180205..cbbfbb7 100644
--- a/src/com/android/settings/applications/ProcStatsEntry.java
+++ b/src/com/android/settings/applications/ProcStatsEntry.java
@@ -16,11 +16,22 @@
package com.android.settings.applications;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.app.ProcessStats;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public final class ProcStatsEntry implements Parcelable {
+ private static final String TAG = "ProcStatsEntry";
-public final class ProcStatsEntry {
final String mPackage;
final int mUid;
final String mName;
@@ -29,7 +40,14 @@ public final class ProcStatsEntry {
final long mAvgPss;
final long mWeight;
- ArrayList<Service> mServices;
+ String mBestTargetPackage;
+
+ ArrayList<Service> mServices = new ArrayList<Service>(2);
+
+ public ApplicationInfo mUiTargetApp;
+ public String mUiLabel;
+ public String mUiBaseLabel;
+ public String mUiPackage;
public ProcStatsEntry(ProcessStats.ProcessState proc,
ProcessStats.ProcessDataCollection tmpTotals) {
@@ -43,18 +61,156 @@ public final class ProcStatsEntry {
mWeight = mDuration * mAvgPss;
}
+ public ProcStatsEntry(Parcel in) {
+ mPackage = in.readString();
+ mUid = in.readInt();
+ mName = in.readString();
+ mUnique = in.readInt() != 0;
+ mDuration = in.readLong();
+ mAvgPss = in.readLong();
+ mWeight = in.readLong();
+ mBestTargetPackage = in.readString();
+ in.readTypedList(mServices, Service.CREATOR);
+ }
+
+ public void evaluateTargetPackage(ProcessStats stats,
+ ProcessStats.ProcessDataCollection totals, Comparator<ProcStatsEntry> compare) {
+ mBestTargetPackage = null;
+ if (mUnique) {
+ mBestTargetPackage = mPackage;
+ addServices(stats.getPackageStateLocked(mPackage, mUid));
+ } else {
+ // See if there is one significant package that was running here.
+ ArrayList<ProcStatsEntry> subProcs = new ArrayList<ProcStatsEntry>();
+ for (int ipkg=0, NPKG=stats.mPackages.getMap().size(); ipkg<NPKG; ipkg++) {
+ SparseArray<ProcessStats.PackageState> uids
+ = stats.mPackages.getMap().valueAt(ipkg);
+ for (int iu=0, NU=uids.size(); iu<NU; iu++) {
+ if (uids.keyAt(iu) != mUid) {
+ continue;
+ }
+ ProcessStats.PackageState pkgState = uids.valueAt(iu);
+ boolean match = false;
+ for (int iproc=0, NPROC=pkgState.mProcesses.size(); iproc<NPROC; iproc++) {
+ ProcessStats.ProcessState subProc =
+ pkgState.mProcesses.valueAt(iproc);
+ if (subProc.mName.equals(mName)) {
+ match = true;
+ subProcs.add(new ProcStatsEntry(subProc, totals));
+ }
+ }
+ if (match) {
+ addServices(stats.getPackageStateLocked(mPackage, mUid));
+ }
+ }
+ }
+ if (subProcs.size() > 1) {
+ Collections.sort(subProcs, compare);
+ if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
+ mBestTargetPackage = subProcs.get(0).mPackage;
+ }
+ }
+ }
+ }
+
+ public void retrieveUiData(PackageManager pm) {
+ mUiTargetApp = null;
+ mUiLabel = mUiBaseLabel = mName;
+ mUiPackage = mBestTargetPackage;
+ if (mUiPackage != null) {
+ // Only one app associated with this process.
+ try {
+ mUiTargetApp = pm.getApplicationInfo(mUiPackage,
+ PackageManager.GET_DISABLED_COMPONENTS |
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ String name = mUiBaseLabel = mUiTargetApp.loadLabel(pm).toString();
+ if (mName.equals(mUiPackage)) {
+ mUiLabel = name;
+ } else {
+ if (mName.startsWith(mUiPackage)) {
+ int off = mUiPackage.length();
+ if (mName.length() > off) {
+ off++;
+ }
+ mUiLabel = name + " (" + mName.substring(off) + ")";
+ } else {
+ mUiLabel = name + " (" + mName + ")";
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ if (mUiTargetApp == null) {
+ String[] packages = pm.getPackagesForUid(mUid);
+ if (packages != null) {
+ for (String curPkg : packages) {
+ try {
+ final PackageInfo pi = pm.getPackageInfo(curPkg,
+ PackageManager.GET_DISABLED_COMPONENTS |
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ if (pi.sharedUserLabel != 0) {
+ mUiTargetApp = pi.applicationInfo;
+ final CharSequence nm = pm.getText(curPkg,
+ pi.sharedUserLabel, pi.applicationInfo);
+ if (nm != null) {
+ mUiBaseLabel = nm.toString();
+ mUiLabel = mUiBaseLabel + " (" + mName + ")";
+ } else {
+ mUiBaseLabel = mUiTargetApp.loadLabel(pm).toString();
+ mUiLabel = mUiBaseLabel + " (" + mName + ")";
+ }
+ break;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ } else {
+ // no current packages for this uid, typically because of uninstall
+ Log.i(TAG, "No package for uid " + mUid);
+ }
+ }
+ }
+
public void addServices(ProcessStats.PackageState pkgState) {
for (int isvc=0, NSVC=pkgState.mServices.size(); isvc<NSVC; isvc++) {
ProcessStats.ServiceState svc = pkgState.mServices.valueAt(isvc);
// XXX can't tell what process it is in!
- if (mServices == null) {
- mServices = new ArrayList<Service>();
- }
mServices.add(new Service(svc));
}
}
- public static final class Service {
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mPackage);
+ dest.writeInt(mUid);
+ dest.writeString(mName);
+ dest.writeInt(mUnique ? 1 : 0);
+ dest.writeLong(mDuration);
+ dest.writeLong(mAvgPss);
+ dest.writeLong(mWeight);
+ dest.writeString(mBestTargetPackage);
+ dest.writeTypedList(mServices);
+ }
+
+ public static final Parcelable.Creator<ProcStatsEntry> CREATOR
+ = new Parcelable.Creator<ProcStatsEntry>() {
+ public ProcStatsEntry createFromParcel(Parcel in) {
+ return new ProcStatsEntry(in);
+ }
+
+ public ProcStatsEntry[] newArray(int size) {
+ return new ProcStatsEntry[size];
+ }
+ };
+
+ public static final class Service implements Parcelable {
final String mPackage;
final String mName;
final long mDuration;
@@ -62,15 +218,51 @@ public final class ProcStatsEntry {
public Service(ProcessStats.ServiceState service) {
mPackage = service.mPackage;
mName = service.mName;
- mDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
+ long startDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_STARTED,
- ProcessStats.STATE_NOTHING, 0, 0)
- + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.STATE_NOTHING, 0, 0);
+ long bindDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_BOUND,
- ProcessStats.STATE_NOTHING, 0, 0)
- + ProcessStats.dumpSingleServiceTime(null, null, service,
+ ProcessStats.STATE_NOTHING, 0, 0);
+ long execDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
ProcessStats.ServiceState.SERVICE_EXEC,
ProcessStats.STATE_NOTHING, 0, 0);
+ if (bindDuration > startDuration) {
+ startDuration = bindDuration;
+ }
+ if (execDuration > startDuration) {
+ startDuration = execDuration;
+ }
+ mDuration = startDuration;
}
+
+ public Service(Parcel in) {
+ mPackage = in.readString();
+ mName = in.readString();
+ mDuration = in.readLong();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mPackage);
+ dest.writeString(mName);
+ dest.writeLong(mDuration);
+ }
+
+ public static final Parcelable.Creator<Service> CREATOR
+ = new Parcelable.Creator<Service>() {
+ public Service createFromParcel(Parcel in) {
+ return new Service(in);
+ }
+
+ public Service[] newArray(int size) {
+ return new Service[size];
+ }
+ };
}
}
diff --git a/src/com/android/settings/applications/ProcessStatsDetail.java b/src/com/android/settings/applications/ProcessStatsDetail.java
new file mode 100644
index 0000000..5ec3b07
--- /dev/null
+++ b/src/com/android/settings/applications/ProcessStatsDetail.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 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.applications;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.Fragment;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.preference.PreferenceActivity;
+import android.text.format.Formatter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import static com.android.settings.Utils.prepareCustomPreferencesList;
+
+public class ProcessStatsDetail extends Fragment implements Button.OnClickListener {
+ private static final String TAG = "ProcessStatsDetail";
+
+ public static final int ACTION_FORCE_STOP = 1;
+
+ public static final String EXTRA_ENTRY = "entry";
+ public static final String EXTRA_MAX_WEIGHT = "max_weight";
+ public static final String EXTRA_TOTAL_TIME = "total_time";
+
+ private PackageManager mPm;
+ private DevicePolicyManager mDpm;
+
+ private ProcStatsEntry mEntry;
+ private long mMaxWeight;
+ private long mTotalTime;
+
+ private View mRootView;
+ private TextView mTitleView;
+ private ViewGroup mTwoButtonsPanel;
+ private Button mForceStopButton;
+ private Button mReportButton;
+ private ViewGroup mDetailsParent;
+ private ViewGroup mServicesParent;
+
+ public static String makePercentString(Resources res, long amount, long total) {
+ final double percent = (((double)amount) / total) * 100;
+ return res.getString(R.string.percentage, (int) Math.ceil(percent));
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mPm = getActivity().getPackageManager();
+ mDpm = (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
+ final Bundle args = getArguments();
+ mEntry = (ProcStatsEntry)args.getParcelable(EXTRA_ENTRY);
+ mEntry.retrieveUiData(mPm);
+ mMaxWeight = args.getLong(EXTRA_MAX_WEIGHT);
+ mTotalTime = args.getLong(EXTRA_TOTAL_TIME);
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.process_stats_details, container, false);
+ prepareCustomPreferencesList(container, view, view, false);
+
+ mRootView = view;
+ createDetails();
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ checkForceStop();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ private void createDetails() {
+ final double percentOfWeight = (((double)mEntry.mWeight) / mMaxWeight) * 100;
+
+ int appLevel = (int) Math.ceil(percentOfWeight);
+ String appLevelText = makePercentString(getResources(), mEntry.mDuration, mTotalTime);
+
+ // Set all values in the header.
+ final TextView summary = (TextView) mRootView.findViewById(android.R.id.summary);
+ summary.setText(mEntry.mName);
+ summary.setVisibility(View.VISIBLE);
+ mTitleView = (TextView) mRootView.findViewById(android.R.id.title);
+ mTitleView.setText(mEntry.mUiBaseLabel);
+ final TextView text1 = (TextView)mRootView.findViewById(android.R.id.text1);
+ text1.setText(appLevelText);
+ final ProgressBar progress = (ProgressBar) mRootView.findViewById(android.R.id.progress);
+ progress.setProgress(appLevel);
+ final ImageView icon = (ImageView) mRootView.findViewById(android.R.id.icon);
+ if (mEntry.mUiTargetApp != null) {
+ icon.setImageDrawable(mEntry.mUiTargetApp.loadIcon(mPm));
+ }
+
+ mTwoButtonsPanel = (ViewGroup)mRootView.findViewById(R.id.two_buttons_panel);
+ mForceStopButton = (Button)mRootView.findViewById(R.id.right_button);
+ mReportButton = (Button)mRootView.findViewById(R.id.left_button);
+ mForceStopButton.setEnabled(false);
+ mReportButton.setVisibility(View.INVISIBLE);
+
+ mDetailsParent = (ViewGroup)mRootView.findViewById(R.id.details);
+ mServicesParent = (ViewGroup)mRootView.findViewById(R.id.services);
+
+ fillDetailsSection();
+ fillServicesSection();
+
+ if (mEntry.mUid >= android.os.Process.FIRST_APPLICATION_UID) {
+ mForceStopButton.setText(R.string.force_stop);
+ mForceStopButton.setTag(ACTION_FORCE_STOP);
+ mForceStopButton.setOnClickListener(this);
+ mTwoButtonsPanel.setVisibility(View.VISIBLE);
+ } else {
+ mTwoButtonsPanel.setVisibility(View.GONE);
+ }
+ }
+
+ public void onClick(View v) {
+ doAction((Integer) v.getTag());
+ }
+
+ private void doAction(int action) {
+ PreferenceActivity pa = (PreferenceActivity)getActivity();
+ switch (action) {
+ case ACTION_FORCE_STOP:
+ killProcesses();
+ break;
+ }
+ }
+
+ private void addDetailsItem(ViewGroup parent, CharSequence label, CharSequence value) {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ ViewGroup item = (ViewGroup) inflater.inflate(R.layout.power_usage_detail_item_text,
+ null);
+ parent.addView(item);
+ TextView labelView = (TextView) item.findViewById(R.id.label);
+ TextView valueView = (TextView) item.findViewById(R.id.value);
+ labelView.setText(label);
+ valueView.setText(value);
+ }
+
+ private void fillDetailsSection() {
+ addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_ram_use),
+ Formatter.formatShortFileSize(getActivity(), mEntry.mAvgPss * 1024));
+ addDetailsItem(mDetailsParent, getResources().getText(R.string.process_stats_run_time),
+ makePercentString(getResources(), mEntry.mDuration, mTotalTime));
+ }
+
+ final static Comparator<ProcStatsEntry.Service> sServiceCompare
+ = new Comparator<ProcStatsEntry.Service>() {
+ @Override
+ public int compare(ProcStatsEntry.Service lhs, ProcStatsEntry.Service rhs) {
+ if (lhs.mDuration < rhs.mDuration) {
+ return 1;
+ } else if (lhs.mDuration > rhs.mDuration) {
+ return -1;
+ }
+ return 0;
+ }
+ };
+
+ private void fillServicesSection() {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ if (mEntry.mServices.size() > 0) {
+ ArrayList<ProcStatsEntry.Service> services =
+ (ArrayList<ProcStatsEntry.Service>)mEntry.mServices.clone();
+ Collections.sort(services, sServiceCompare);
+ for (int i=0; i<services.size(); i++) {
+ ProcStatsEntry.Service service = services.get(i);
+ String label = service.mName;
+ int tail = label.lastIndexOf('.');
+ if (tail >= 0 && tail < (label.length()-1)) {
+ label = label.substring(tail+1);
+ }
+ long duration = service.mDuration;
+ final double percentOfTime = (((double)duration) / mTotalTime) * 100;
+ addDetailsItem(mServicesParent, label, getActivity().getResources().getString(
+ R.string.percentage, (int) Math.ceil(percentOfTime)));
+ }
+ }
+ }
+
+ private void killProcesses() {
+ ActivityManager am = (ActivityManager)getActivity().getSystemService(
+ Context.ACTIVITY_SERVICE);
+ am.forceStopPackage(mEntry.mUiPackage);
+ checkForceStop();
+ }
+
+ private final BroadcastReceiver mCheckKillProcessesReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mForceStopButton.setEnabled(getResultCode() != Activity.RESULT_CANCELED);
+ }
+ };
+
+ private void checkForceStop() {
+ if (mEntry.mUiPackage == null || mEntry.mUid < Process.FIRST_APPLICATION_UID) {
+ mForceStopButton.setEnabled(false);
+ return;
+ }
+ if (mDpm.packageHasActiveAdmins(mEntry.mUiPackage)) {
+ mForceStopButton.setEnabled(false);
+ return;
+ }
+ try {
+ ApplicationInfo info = mPm.getApplicationInfo(mEntry.mUiPackage, 0);
+ if ((info.flags&ApplicationInfo.FLAG_STOPPED) == 0) {
+ mForceStopButton.setEnabled(true);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ Intent intent = new Intent(Intent.ACTION_QUERY_PACKAGE_RESTART,
+ Uri.fromParts("package", mEntry.mUiPackage, null));
+ intent.putExtra(Intent.EXTRA_PACKAGES, new String[] { mEntry.mUiPackage });
+ intent.putExtra(Intent.EXTRA_UID, mEntry.mUid);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, mEntry.mUid);
+ getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
+ Activity.RESULT_CANCELED, null, null);
+ }
+}
diff --git a/src/com/android/settings/applications/ProcessStatsPreference.java b/src/com/android/settings/applications/ProcessStatsPreference.java
index 64ab0b6..2dea96a 100644
--- a/src/com/android/settings/applications/ProcessStatsPreference.java
+++ b/src/com/android/settings/applications/ProcessStatsPreference.java
@@ -27,15 +27,21 @@ import android.widget.TextView;
import com.android.settings.R;
public class ProcessStatsPreference extends Preference {
+ private final ProcStatsEntry mEntry;
private int mProgress;
private CharSequence mProgressText;
- public ProcessStatsPreference(Context context, Drawable icon) {
+ public ProcessStatsPreference(Context context, Drawable icon, ProcStatsEntry entry) {
super(context);
+ mEntry = entry;
setLayoutResource(R.layout.app_percentage_item);
setIcon(icon != null ? icon : new ColorDrawable(0));
}
+ public ProcStatsEntry getEntry() {
+ return mEntry;
+ }
+
public void setPercent(double percentOfWeight, double percentOfTime) {
mProgress = (int) Math.ceil(percentOfWeight);
mProgressText = getContext().getResources().getString(
diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java
index 8e98d23..49682ed 100644
--- a/src/com/android/settings/applications/ProcessStatsUi.java
+++ b/src/com/android/settings/applications/ProcessStatsUi.java
@@ -17,8 +17,6 @@
package com.android.settings.applications;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Parcel;
@@ -28,10 +26,10 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.preference.Preference;
+import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
-import android.text.format.DateFormat;
import android.util.Log;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -83,6 +81,7 @@ public class ProcessStatsUi extends PreferenceFragment {
private PreferenceGroup mAppListGroup;
private Preference mMemStatusPref;
+ long mMaxWeight;
long mTotalTime;
@Override
@@ -127,11 +126,13 @@ public class ProcessStatsUi extends PreferenceFragment {
return false;
}
- /*
- PreferenceActivity pa = (PreferenceActivity)getActivity();
- pa.startPreferencePanel(PowerUsageDetail.class.getName(), args,
- R.string.details_title, null, null, 0);
- */
+ ProcessStatsPreference pgp = (ProcessStatsPreference) preference;
+ Bundle args = new Bundle();
+ args.putParcelable(ProcessStatsDetail.EXTRA_ENTRY, pgp.getEntry());
+ args.putLong(ProcessStatsDetail.EXTRA_MAX_WEIGHT, mMaxWeight);
+ args.putLong(ProcessStatsDetail.EXTRA_TOTAL_TIME, mTotalTime);
+ ((PreferenceActivity) getActivity()).startPreferencePanel(
+ ProcessStatsDetail.class.getName(), args, R.string.details_title, null, null, 0);
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
@@ -263,108 +264,19 @@ public class ProcessStatsUi extends PreferenceFragment {
maxWeight = proc.mWeight;
}
}
+ mMaxWeight = maxWeight;
for (int i=0, N=(procs != null ? procs.size() : 0); i<N; i++) {
ProcStatsEntry proc = procs.get(i);
final double percentOfWeight = (((double)proc.mWeight) / maxWeight) * 100;
final double percentOfTime = (((double)proc.mDuration) / mTotalTime) * 100;
if (percentOfWeight < 1) continue;
- ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null);
- ApplicationInfo targetApp = null;
- String label = proc.mName;
- String pkgName = null;
- if (proc.mUnique) {
- pkgName = proc.mPackage;
- proc.addServices(mStats.getPackageStateLocked(proc.mPackage, proc.mUid));
- } else {
- // See if there is one significant package that was running here.
- ArrayList<ProcStatsEntry> subProcs = new ArrayList<ProcStatsEntry>();
- for (int ipkg=0, NPKG=mStats.mPackages.getMap().size(); ipkg<NPKG; ipkg++) {
- SparseArray<ProcessStats.PackageState> uids
- = mStats.mPackages.getMap().valueAt(ipkg);
- for (int iu=0, NU=uids.size(); iu<NU; iu++) {
- if (uids.keyAt(iu) != proc.mUid) {
- continue;
- }
- ProcessStats.PackageState pkgState = uids.valueAt(iu);
- boolean match = false;
- for (int iproc=0, NPROC=pkgState.mProcesses.size(); iproc<NPROC; iproc++) {
- ProcessStats.ProcessState subProc =
- pkgState.mProcesses.valueAt(iproc);
- if (subProc.mName.equals(proc.mName)) {
- match = true;
- subProcs.add(new ProcStatsEntry(subProc, totals));
- }
- }
- if (match) {
- proc.addServices(mStats.getPackageStateLocked(proc.mPackage,
- proc.mUid));
- }
- }
- }
- if ( subProcs.size() > 1) {
- Collections.sort(subProcs, sEntryCompare);
- if (subProcs.get(0).mWeight > (subProcs.get(1).mWeight*3)) {
- pkgName = subProcs.get(0).mPackage;
- }
- }
- }
- if (pkgName != null) {
- // Only one app associated with this process.
- try {
- targetApp = pm.getApplicationInfo(pkgName,
- PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
- PackageManager.GET_UNINSTALLED_PACKAGES);
- String name = targetApp.loadLabel(pm).toString();
- if (proc.mName.equals(pkgName)) {
- label = name;
- } else {
- if (proc.mName.startsWith(pkgName)) {
- int off = pkgName.length();
- if (proc.mName.length() > off) {
- off++;
- }
- label = name + " (" + proc.mName.substring(off) + ")";
- } else {
- label = name + " (" + proc.mName + ")";
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- }
- }
- if (targetApp == null) {
- String[] packages = pm.getPackagesForUid(proc.mUid);
- if (packages != null) {
- for (String curPkg : packages) {
- try {
- final PackageInfo pi = pm.getPackageInfo(curPkg,
- PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
- PackageManager.GET_UNINSTALLED_PACKAGES);
- if (pi.sharedUserLabel != 0) {
- targetApp = pi.applicationInfo;
- final CharSequence nm = pm.getText(curPkg,
- pi.sharedUserLabel, pi.applicationInfo);
- if (nm != null) {
- label = nm.toString() + " (" + proc.mName + ")";
- } else {
- label = targetApp.loadLabel(pm).toString() + " ("
- + proc.mName + ")";
- }
- break;
- }
- } catch (PackageManager.NameNotFoundException e) {
- }
- }
- } else {
- // no current packages for this uid, typically because of uninstall
- Log.i(TAG, "No package for uid " + proc.mUid);
- }
- }
- pref.setTitle(label);
- if (targetApp != null) {
- pref.setIcon(targetApp.loadIcon(pm));
+ ProcessStatsPreference pref = new ProcessStatsPreference(getActivity(), null, proc);
+ proc.evaluateTargetPackage(mStats, totals, sEntryCompare);
+ proc.retrieveUiData(pm);
+ pref.setTitle(proc.mUiLabel);
+ if (proc.mUiTargetApp != null) {
+ pref.setIcon(proc.mUiTargetApp.loadIcon(pm));
}
pref.setOrder(i);
pref.setPercent(percentOfWeight, percentOfTime);
diff --git a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
index 3b1ea93..953ff3d 100644
--- a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
+++ b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
@@ -320,7 +320,12 @@ public class BatteryStatsHelper {
R.string.details_title, null, null, 0);
}
- public void refreshStats() {
+ /**
+ * Refreshes the power usage list.
+ * @param includeZeroConsumption whether includes those applications which have consumed very
+ * little power up till now.
+ */
+ public void refreshStats(boolean includeZeroConsumption) {
// Initialize mStats if necessary.
getStats();
@@ -336,7 +341,7 @@ public class BatteryStatsHelper {
mUserSippers.clear();
mUserPower.clear();
- processAppUsage();
+ processAppUsage(includeZeroConsumption);
processMiscUsage();
Collections.sort(mUsageList);
@@ -356,7 +361,7 @@ public class BatteryStatsHelper {
}
}
- private void processAppUsage() {
+ private void processAppUsage(boolean includeZeroConsumption) {
SensorManager sensorManager = (SensorManager) mActivity.getSystemService(
Context.SENSOR_SERVICE);
final int which = mStatsType;
@@ -522,7 +527,7 @@ public class BatteryStatsHelper {
// Add the app to the list if it is consuming power
boolean isOtherUser = false;
final int userId = UserHandle.getUserId(u.getUid());
- if (power != 0 || u.getUid() == 0) {
+ if (power != 0 || includeZeroConsumption || u.getUid() == 0) {
BatterySipper app = new BatterySipper(mActivity, mRequestQueue, mHandler,
packageWithHighestDrain, DrainType.APP, 0, u,
new double[] {power});
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index e9b8106..ca159dc 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -36,6 +36,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Process;
+import android.os.UserHandle;
import android.preference.PreferenceActivity;
import android.provider.Settings;
import android.text.TextUtils;
@@ -470,7 +471,7 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
Uri.fromParts("package", mPackages[0], null));
intent.putExtra(Intent.EXTRA_PACKAGES, mPackages);
intent.putExtra(Intent.EXTRA_UID, mUid);
- intent.putExtra(Intent.EXTRA_USER_HANDLE, mUid);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(mUid));
getActivity().sendOrderedBroadcast(intent, null, mCheckKillProcessesReceiver, null,
Activity.RESULT_CANCELED, null, null);
}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 480bb4e..740fdb5 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -210,7 +210,7 @@ public class PowerUsageSummary extends PreferenceFragment {
addNotAvailableMessage();
return;
}
- mStatsHelper.refreshStats();
+ mStatsHelper.refreshStats(false);
List<BatterySipper> usageList = mStatsHelper.getUsageList();
for (BatterySipper sipper : usageList) {
if (sipper.getSortValue() < MIN_POWER_THRESHOLD) continue;
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 815be41..6dceea9 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -55,7 +55,7 @@ public class LocationSettings extends LocationSettingsBase
/** Key for preference category "Recent location requests" */
private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests";
/** Key for preference category "Location services" */
- private static final String KEY_LOCATION_SERVICES = "location_services";
+ private static final String KEY_APP_SETTINGS = "app_settings";
private Switch mSwitch;
private boolean mValidListener;
@@ -165,10 +165,10 @@ public class LocationSettings extends LocationSettingsBase
categoryRecentLocationRequests.addPreference(banner);
}
- PreferenceCategory categoryLocationServices =
- (PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES);
+ PreferenceCategory categoryAppSettings =
+ (PreferenceCategory) root.findPreference(KEY_APP_SETTINGS);
final SettingsInjector injector = new SettingsInjector(activity);
- List<Preference> locationServices = injector.getInjectedSettings();
+ List<Preference> appSettings = injector.getInjectedSettings();
mReceiver = new BroadcastReceiver() {
@Override
@@ -182,11 +182,11 @@ public class LocationSettings extends LocationSettingsBase
activity.registerReceiver(mReceiver,
new IntentFilter(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED));
- if (locationServices.size() > 0) {
- addPreferencesSorted(locationServices, categoryLocationServices);
+ if (appSettings.size() > 0) {
+ addPreferencesSorted(appSettings, categoryAppSettings);
} else {
// If there's no item to display, remove the whole category.
- root.removePreference(categoryLocationServices);
+ root.removePreference(categoryAppSettings);
}
// Only show the master switch when we're not in multi-pane mode, and not being used as
@@ -233,9 +233,12 @@ public class LocationSettings extends LocationSettingsBase
break;
}
- boolean enabled = (mode != Settings.Secure.LOCATION_MODE_OFF) && !restricted;
+ // Restricted user can't change the location mode, so disable the master switch. But in some
+ // corner cases, the location might still be enabled. In such case the master switch should
+ // be disabled but checked.
+ boolean enabled = (mode != Settings.Secure.LOCATION_MODE_OFF);
mSwitch.setEnabled(!restricted);
- mLocationMode.setEnabled(enabled);
+ mLocationMode.setEnabled(enabled && !restricted);
if (enabled != mSwitch.isChecked()) {
// set listener to null so that that code below doesn't trigger onCheckedChanged()
diff --git a/src/com/android/settings/location/LocationSettingsBase.java b/src/com/android/settings/location/LocationSettingsBase.java
index 81e841a..9ceefe7 100644
--- a/src/com/android/settings/location/LocationSettingsBase.java
+++ b/src/com/android/settings/location/LocationSettingsBase.java
@@ -38,12 +38,29 @@ public abstract class LocationSettingsBase extends SettingsPreferenceFragment
private static final int LOADER_ID_LOCATION_MODE = 1;
+ /**
+ * Whether the fragment is actively running.
+ */
+ private boolean mActive = false;
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
getLoaderManager().initLoader(LOADER_ID_LOCATION_MODE, null, this);
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ mActive = true;
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mActive = false;
+ }
+
/** Called when location mode has changed. */
public abstract void onModeChanged(int mode, boolean restricted);
@@ -61,7 +78,9 @@ public abstract class LocationSettingsBase extends SettingsPreferenceFragment
}
mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
Settings.Secure.LOCATION_MODE_OFF);
- onModeChanged(mode, true);
+ if (mActive) {
+ onModeChanged(mode, true);
+ }
return;
}
Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, mode);
@@ -69,9 +88,11 @@ public abstract class LocationSettingsBase extends SettingsPreferenceFragment
}
public void refreshLocationMode() {
- int mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
- Settings.Secure.LOCATION_MODE_OFF);
- onModeChanged(mode, isRestricted());
+ if (mActive) {
+ int mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE,
+ Settings.Secure.LOCATION_MODE_OFF);
+ onModeChanged(mode, isRestricted());
+ }
}
@Override
diff --git a/src/com/android/settings/location/RecentLocationApps.java b/src/com/android/settings/location/RecentLocationApps.java
index 23e6dcf..1fa8aac 100644
--- a/src/com/android/settings/location/RecentLocationApps.java
+++ b/src/com/android/settings/location/RecentLocationApps.java
@@ -140,7 +140,7 @@ public class RecentLocationApps {
public List<Preference> getAppList() {
// Retrieve Uid-based battery blaming info and generate a package to BatterySipper HashMap
// for later faster looking up.
- mStatsHelper.refreshStats();
+ mStatsHelper.refreshStats(true);
List<BatterySipper> usageList = mStatsHelper.getUsageList();
// Key: package Uid. Value: BatterySipperWrapper.
HashMap<Integer, BatterySipperWrapper> sipperMap =
@@ -243,11 +243,22 @@ public class RecentLocationApps {
try {
ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
packageName, PackageManager.GET_META_DATA);
- pref = createRecentLocationEntry(
- mPackageManager.getApplicationIcon(appInfo),
- mPackageManager.getApplicationLabel(appInfo),
- highBattery,
- new PackageEntryClickedListener(packageName));
+ // Multiple users can install the same package. Each user gets a different Uid for
+ // the same package.
+ //
+ // Here we retrieve the Uid with package name, that will be the Uid for that package
+ // associated with the current active user. If the Uid differs from the Uid in ops,
+ // that means this entry belongs to another inactive user and we should ignore that.
+ if (appInfo.uid == ops.getUid()) {
+ pref = createRecentLocationEntry(
+ mPackageManager.getApplicationIcon(appInfo),
+ mPackageManager.getApplicationLabel(appInfo),
+ highBattery,
+ new PackageEntryClickedListener(packageName));
+ } else if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "package " + packageName + " with Uid " + ops.getUid() +
+ " belongs to another inactive account, ignored.");
+ }
} catch (PackageManager.NameNotFoundException e) {
Log.wtf(TAG, "Package not found: " + packageName);
}
diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java
index 7bd190c..5929466 100644
--- a/src/com/android/settings/location/SettingsInjector.java
+++ b/src/com/android/settings/location/SettingsInjector.java
@@ -30,6 +30,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
+import android.os.SystemClock;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
@@ -42,7 +43,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -67,22 +67,6 @@ class SettingsInjector {
private static final long INJECTED_STATUS_UPDATE_TIMEOUT_MILLIS = 1000;
/**
- * Intent action marking the receiver as injecting a setting
- */
- public static final String RECEIVER_INTENT = "com.android.settings.InjectedLocationSetting";
-
- /**
- * Name of the meta-data tag used to specify the resource file that includes the settings
- * attributes.
- */
- public static final String META_DATA_NAME = "com.android.settings.InjectedLocationSetting";
-
- /**
- * Name of the XML tag that includes the attributes for the setting.
- */
- public static final String ATTRIBUTES_NAME = "injected-location-setting";
-
- /**
* {@link Message#what} value for starting to load status values
* in case we aren't already in the process of loading them.
*/
@@ -115,7 +99,8 @@ class SettingsInjector {
/**
* Returns a list with one {@link InjectedSetting} object for each {@link android.app.Service}
- * that responds to {@link #RECEIVER_INTENT} and provides the expected setting metadata.
+ * that responds to {@link SettingInjectorService#ACTION_SERVICE_INTENT} and provides the
+ * expected setting metadata.
*
* Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
*
@@ -123,37 +108,38 @@ class SettingsInjector {
*/
private List<InjectedSetting> getSettings() {
PackageManager pm = mContext.getPackageManager();
- Intent receiverIntent = new Intent(RECEIVER_INTENT);
+ Intent intent = new Intent(SettingInjectorService.ACTION_SERVICE_INTENT);
List<ResolveInfo> resolveInfos =
- pm.queryIntentServices(receiverIntent, PackageManager.GET_META_DATA);
+ pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Found services: " + resolveInfos);
}
List<InjectedSetting> settings = new ArrayList<InjectedSetting>(resolveInfos.size());
- for (ResolveInfo receiver : resolveInfos) {
+ for (ResolveInfo resolveInfo : resolveInfos) {
try {
- InjectedSetting info = parseServiceInfo(receiver, pm);
- if (info == null) {
- Log.w(TAG, "Unable to load service info " + receiver);
+ InjectedSetting setting = parseServiceInfo(resolveInfo, pm);
+ if (setting == null) {
+ Log.w(TAG, "Unable to load service info " + resolveInfo);
} else {
- if (Log.isLoggable(TAG, Log.INFO)) {
- Log.i(TAG, "Loaded service info: " + info);
- }
- settings.add(info);
+ settings.add(setting);
}
} catch (XmlPullParserException e) {
- Log.w(TAG, "Unable to load service info " + receiver, e);
+ Log.w(TAG, "Unable to load service info " + resolveInfo, e);
} catch (IOException e) {
- Log.w(TAG, "Unable to load service info " + receiver, e);
+ Log.w(TAG, "Unable to load service info " + resolveInfo, e);
}
}
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Loaded settings: " + settings);
+ }
return settings;
}
/**
- * Parses {@link InjectedSetting} from the attributes of the {@link #META_DATA_NAME} tag.
+ * Parses {@link InjectedSetting} from the attributes of the
+ * {@link SettingInjectorService#META_DATA_NAME} tag.
*
* Duplicates some code from {@link android.content.pm.RegisteredServicesCache}.
*/
@@ -164,9 +150,9 @@ class SettingsInjector {
XmlResourceParser parser = null;
try {
- parser = si.loadXmlMetaData(pm, META_DATA_NAME);
+ parser = si.loadXmlMetaData(pm, SettingInjectorService.META_DATA_NAME);
if (parser == null) {
- throw new XmlPullParserException("No " + META_DATA_NAME
+ throw new XmlPullParserException("No " + SettingInjectorService.META_DATA_NAME
+ " meta-data for " + service + ": " + si);
}
@@ -178,9 +164,9 @@ class SettingsInjector {
}
String nodeName = parser.getName();
- if (!ATTRIBUTES_NAME.equals(nodeName)) {
+ if (!SettingInjectorService.ATTRIBUTES_NAME.equals(nodeName)) {
throw new XmlPullParserException("Meta-data does not start with "
- + ATTRIBUTES_NAME + " tag");
+ + SettingInjectorService.ATTRIBUTES_NAME + " tag");
}
Resources res = pm.getResourcesForApplication(si.applicationInfo);
@@ -201,15 +187,15 @@ class SettingsInjector {
private static InjectedSetting parseAttributes(
String packageName, String className, Resources res, AttributeSet attrs) {
- TypedArray sa = res.obtainAttributes(attrs, android.R.styleable.InjectedLocationSetting);
+ TypedArray sa = res.obtainAttributes(attrs, android.R.styleable.SettingInjectorService);
try {
// Note that to help guard against malicious string injection, we do not allow dynamic
// specification of the label (setting title)
- final String label = sa.getString(android.R.styleable.InjectedLocationSetting_label);
+ final String label = sa.getString(android.R.styleable.SettingInjectorService_title);
final int iconId = sa.getResourceId(
- android.R.styleable.InjectedLocationSetting_icon, 0);
+ android.R.styleable.SettingInjectorService_icon, 0);
final String settingsActivity =
- sa.getString(android.R.styleable.InjectedLocationSetting_settingsActivity);
+ sa.getString(android.R.styleable.SettingInjectorService_settingsActivity);
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "parsed label: " + label + ", iconId: " + iconId
+ ", settingsActivity: " + settingsActivity);
@@ -306,6 +292,7 @@ class SettingsInjector {
break;
case WHAT_RECEIVED_STATUS:
final Setting receivedSetting = (Setting) msg.obj;
+ receivedSetting.maybeLogElapsedTime();
mSettingsBeingLoaded.remove(receivedSetting);
mTimedOutSettings.remove(receivedSetting);
removeMessages(WHAT_TIMEOUT, receivedSetting);
@@ -357,8 +344,7 @@ class SettingsInjector {
iter.remove();
// Request the status value
- Intent intent = setting.createUpdatingIntent();
- mContext.startService(intent);
+ setting.startService();
mSettingsBeingLoaded.add(setting);
// Ensure that if receiving the status value takes too long, we start loading the
@@ -390,6 +376,7 @@ class SettingsInjector {
public final InjectedSetting setting;
public final Preference preference;
+ public long startMillis;
private Setting(InjectedSetting setting, Preference preference) {
this.setting = setting;
@@ -406,7 +393,7 @@ class SettingsInjector {
/**
* Returns true if they both have the same {@link #setting} value. Ignores mutable
- * preference so that it's safe to use in sets.
+ * {@link #preference} and {@link #startMillis} so that it's safe to use in sets.
*/
@Override
public boolean equals(Object o) {
@@ -419,11 +406,10 @@ class SettingsInjector {
}
/**
- * Creates an Intent to ask the receiver for the current status for the setting, and display
- * it when it replies.
+ * Starts the service to fetch for the current status for the setting, and updates the
+ * preference when the service replies.
*/
- public Intent createUpdatingIntent() {
- final Intent receiverIntent = setting.getServiceIntent();
+ public void startService() {
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -440,12 +426,25 @@ class SettingsInjector {
}
};
Messenger messenger = new Messenger(handler);
- receiverIntent.putExtra(SettingInjectorService.MESSENGER_KEY, messenger);
+
+ Intent intent = setting.getServiceIntent();
+ intent.putExtra(SettingInjectorService.MESSENGER_KEY, messenger);
+
if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, setting + ": sending rcv-intent: " + receiverIntent
+ Log.d(TAG, setting + ": sending update intent: " + intent
+ ", handler: " + handler);
+ startMillis = SystemClock.elapsedRealtime();
+ } else {
+ startMillis = 0;
+ }
+ mContext.startService(intent);
+ }
+
+ public void maybeLogElapsedTime() {
+ if (Log.isLoggable(TAG, Log.DEBUG) && startMillis != 0) {
+ long end = SystemClock.elapsedRealtime();
+ Log.d(TAG, this + " update took " + (end - startMillis) + " millis");
}
- return receiverIntent;
}
}
}
diff --git a/src/com/android/settings/nfc/PaymentBackend.java b/src/com/android/settings/nfc/PaymentBackend.java
index 3c2c3ce..e2f110f 100644
--- a/src/com/android/settings/nfc/PaymentBackend.java
+++ b/src/com/android/settings/nfc/PaymentBackend.java
@@ -22,7 +22,7 @@ import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.nfc.NfcAdapter;
import android.nfc.cardemulation.ApduServiceInfo;
-import android.nfc.cardemulation.CardEmulationManager;
+import android.nfc.cardemulation.CardEmulation;
import android.provider.Settings;
import java.util.ArrayList;
@@ -40,19 +40,19 @@ public class PaymentBackend {
private final Context mContext;
private final NfcAdapter mAdapter;
- private final CardEmulationManager mCardEmuManager;
+ private final CardEmulation mCardEmuManager;
public PaymentBackend(Context context) {
mContext = context;
mAdapter = NfcAdapter.getDefaultAdapter(context);
- mCardEmuManager = CardEmulationManager.getInstance(mAdapter);
+ mCardEmuManager = CardEmulation.getInstance(mAdapter);
}
public List<PaymentAppInfo> getPaymentAppInfos() {
PackageManager pm = mContext.getPackageManager();
List<ApduServiceInfo> serviceInfos =
- mCardEmuManager.getServices(CardEmulationManager.CATEGORY_PAYMENT);
+ mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT);
List<PaymentAppInfo> appInfos = new ArrayList<PaymentAppInfo>();
if (serviceInfos == null) return appInfos;
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index a6887a3..ae2f4c1 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -22,7 +22,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.nfc.cardemulation.CardEmulationManager;
+import android.nfc.cardemulation.CardEmulation;
import android.os.Bundle;
import android.util.Log;
@@ -47,8 +47,8 @@ public final class PaymentDefaultDialog extends AlertActivity implements
mBackend = new PaymentBackend(this);
Intent intent = getIntent();
ComponentName component = intent.getParcelableExtra(
- CardEmulationManager.EXTRA_SERVICE_COMPONENT);
- String category = intent.getStringExtra(CardEmulationManager.EXTRA_CATEGORY);
+ CardEmulation.EXTRA_SERVICE_COMPONENT);
+ String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY);
setResult(RESULT_CANCELED);
if (!buildDialog(component, category)) {
@@ -75,7 +75,7 @@ public final class PaymentDefaultDialog extends AlertActivity implements
return false;
}
- if (!CardEmulationManager.CATEGORY_PAYMENT.equals(category)) {
+ if (!CardEmulation.CATEGORY_PAYMENT.equals(category)) {
Log.e(TAG, "Don't support defaults for category " + category);
return false;
}
diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java
index 41bcc2c..af569ac 100644
--- a/src/com/android/settings/nfc/PaymentSettings.java
+++ b/src/com/android/settings/nfc/PaymentSettings.java
@@ -55,23 +55,10 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
for (PaymentAppInfo appInfo : appInfos) {
PaymentAppPreference preference =
new PaymentAppPreference(getActivity(), appInfo, this);
- // If for some reason isAuto gets out of sync, clear out app default
preference.setIcon(appInfo.icon);
preference.setTitle(appInfo.caption);
screen.addPreference(preference);
}
- if (appInfos.size() > 1) {
- PaymentAppInfo appInfo = new PaymentAppInfo();
- appInfo.icon = null;
- appInfo.componentName = null;
- appInfo.isDefault = !(mPaymentBackend.getDefaultPaymentApp() != null);
- // Add "Ask every time" option
- PaymentAppPreference preference =
- new PaymentAppPreference(getActivity(), appInfo, this);
- preference.setIcon(null);
- preference.setTitle(R.string.nfc_payment_ask);
- screen.addPreference(preference);
- }
}
setPreferenceScreen(screen);
}
@@ -82,8 +69,6 @@ public class PaymentSettings extends SettingsPreferenceFragment implements
PaymentAppInfo appInfo = (PaymentAppInfo) v.getTag();
if (appInfo.componentName != null) {
mPaymentBackend.setDefaultPaymentApp(appInfo.componentName);
- } else {
- mPaymentBackend.setDefaultPaymentApp(null);
}
refresh();
}
diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java
index c697661..52ee4fd 100644
--- a/src/com/android/settings/tts/TextToSpeechSettings.java
+++ b/src/com/android/settings/tts/TextToSpeechSettings.java
@@ -288,7 +288,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements
if (defaultAvailable == TextToSpeech.LANG_NOT_SUPPORTED ||
defaultAvailable == TextToSpeech.LANG_MISSING_DATA ||
- mAvailableStrLocals != null && notInAvailableLangauges) {
+ mAvailableStrLocals == null || notInAvailableLangauges) {
if (DBG) Log.d(TAG, "Default locale for this TTS engine is not supported.");
updateEngineStatus(R.string.tts_status_not_supported);
updateWidgetState(false);
diff --git a/src/com/android/settings/wfd/WifiDisplaySettings.java b/src/com/android/settings/wfd/WifiDisplaySettings.java
index 7f560b3..6ec79f3 100755
--- a/src/com/android/settings/wfd/WifiDisplaySettings.java
+++ b/src/com/android/settings/wfd/WifiDisplaySettings.java
@@ -33,6 +33,7 @@ import android.net.Uri;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
+import android.net.wifi.WpsInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -94,6 +95,7 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment {
private PreferenceGroup mCertCategory;
private boolean mListen;
private boolean mAutoGO;
+ private int mWpsConfig = WpsInfo.INVALID;
private int mListenChannel;
private int mOperatingChannel;
@@ -160,6 +162,8 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment {
Settings.Global.WIFI_DISPLAY_ON), false, mSettingsObserver);
getContentResolver().registerContentObserver(Settings.Global.getUriFor(
Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON), false, mSettingsObserver);
+ getContentResolver().registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.WIFI_DISPLAY_WPS_CONFIG), false, mSettingsObserver);
mDisplayManager.scanWifiDisplays();
@@ -222,6 +226,8 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment {
Settings.Global.WIFI_DISPLAY_ON, 0) != 0;
mWifiDisplayCertificationOn = Settings.Global.getInt(getContentResolver(),
Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0;
+ mWpsConfig = Settings.Global.getInt(getContentResolver(),
+ Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
mWifiDisplayStatus = mDisplayManager.getWifiDisplayStatus();
applyState();
@@ -367,12 +373,41 @@ public final class WifiDisplaySettings extends SettingsPreferenceFragment {
cbp.setChecked(mAutoGO);
mCertCategory.addPreference(cbp);
- // Drop down list for choosing listen channel
+ // Drop down list for choosing WPS method (PBC/KEYPAD/DISPLAY)
ListPreference lp = new ListPreference(getActivity()) {
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
+ mWpsConfig = Integer.parseInt(getValue());
+ setSummary("%1$s");
+ getActivity().invalidateOptionsMenu();
+ Settings.Global.putInt(getActivity().getContentResolver(),
+ Settings.Global.WIFI_DISPLAY_WPS_CONFIG, mWpsConfig);
+ }
+ }
+ };
+ mWpsConfig = Settings.Global.getInt(getActivity().getContentResolver(),
+ Settings.Global.WIFI_DISPLAY_WPS_CONFIG, WpsInfo.INVALID);
+ String[] wpsEntries = { "Default", "PBC", "KEYPAD", "DISPLAY" };
+ String[] wpsValues = {
+ "" + WpsInfo.INVALID,
+ "" + WpsInfo.PBC,
+ "" + WpsInfo.KEYPAD,
+ "" + WpsInfo.DISPLAY };
+ lp.setTitle(R.string.wifi_display_wps_config);
+ lp.setEntries(wpsEntries);
+ lp.setEntryValues(wpsValues);
+ lp.setValue("" + mWpsConfig);
+ lp.setSummary("%1$s");
+ mCertCategory.addPreference(lp);
+
+ // Drop down list for choosing listen channel
+ lp = new ListPreference(getActivity()) {
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ super.onDialogClosed(positiveResult);
+ if (positiveResult) {
mListenChannel = Integer.parseInt(getValue());
setSummary("%1$s");
getActivity().invalidateOptionsMenu();
diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
index bf3f497..85a0494 100644
--- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java
+++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
@@ -800,7 +800,7 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
sWifiState.onActualStateChange(context, intent);
} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
sBluetoothState.onActualStateChange(context, intent);
- } else if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(action)) {
+ } else if (LocationManager.MODE_CHANGED_ACTION.equals(action)) {
sLocationState.onActualStateChange(context, intent);
} else if (ContentResolver.ACTION_SYNC_CONN_STATUS_CHANGED.equals(action)) {
sSyncState.onActualStateChange(context, intent);
diff --git a/src/com/android/settings/wifi/AccessPoint.java b/src/com/android/settings/wifi/AccessPoint.java
index 20146eb..c4d1f7c 100644
--- a/src/com/android/settings/wifi/AccessPoint.java
+++ b/src/com/android/settings/wifi/AccessPoint.java
@@ -16,6 +16,8 @@
package com.android.settings.wifi;
+import com.android.settings.R;
+
import android.content.Context;
import android.net.NetworkInfo.DetailedState;
import android.net.wifi.ScanResult;
@@ -29,8 +31,6 @@ import android.util.Log;
import android.view.View;
import android.widget.ImageView;
-import com.android.settings.R;
-
class AccessPoint extends Preference {
static final String TAG = "Settings.AccessPoint";
@@ -211,7 +211,8 @@ class AccessPoint extends Preference {
signal.setImageDrawable(null);
} else {
signal.setImageLevel(getLevel());
- signal.setImageResource(R.drawable.wifi_signal);
+ signal.setImageDrawable(getContext().getTheme().obtainStyledAttributes(
+ new int[] {R.attr.wifi_signal}).getDrawable(0));
signal.setImageState((security != SECURITY_NONE) ?
STATE_SECURED : STATE_NONE, true);
}
diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java
index 82b0cc6..f1720c1 100644
--- a/src/com/android/settings/wifi/WifiDialog.java
+++ b/src/com/android/settings/wifi/WifiDialog.java
@@ -38,7 +38,7 @@ class WifiDialog extends AlertDialog implements WifiConfigUiBase {
public WifiDialog(Context context, DialogInterface.OnClickListener listener,
AccessPoint accessPoint, boolean edit) {
- super(context, R.style.Theme_WifiDialog);
+ super(context);
mEdit = edit;
mListener = listener;
mAccessPoint = accessPoint;
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 9fc1010..1caf58b 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -19,12 +19,9 @@ package com.android.settings.wifi;
import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
import static android.os.UserManager.DISALLOW_CONFIG_WIFI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
+import com.android.settings.R;
+import com.android.settings.RestrictedSettingsFragment;
+import com.android.settings.wifi.p2p.WifiP2pSettings;
import android.app.ActionBar;
import android.app.Activity;
@@ -37,6 +34,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
@@ -76,9 +74,12 @@ import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
-import com.android.settings.R;
-import com.android.settings.RestrictedSettingsFragment;
-import com.android.settings.wifi.p2p.WifiP2pSettings;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* Two types of UI are provided here.
@@ -134,7 +135,7 @@ public class WifiSettings extends RestrictedSettingsFragment
private DetailedState mLastState;
private WifiInfo mLastInfo;
- private AtomicBoolean mConnected = new AtomicBoolean(false);
+ private final AtomicBoolean mConnected = new AtomicBoolean(false);
private WifiDialog mDialog;
@@ -447,10 +448,11 @@ public class WifiSettings extends RestrictedSettingsFragment
if (isRestrictedAndNotPinProtected()) return;
final boolean wifiIsEnabled = mWifiManager.isWifiEnabled();
+ TypedArray ta = getActivity().getTheme().obtainStyledAttributes(
+ new int[] {R.attr.ic_menu_add, R.attr.ic_wps});
if (mSetupWizardMode) {
- // FIXME: add setIcon() when graphics are available
menu.add(Menu.NONE, MENU_ID_WPS_PBC, 0, R.string.wifi_menu_wps_pbc)
- .setIcon(R.drawable.ic_wps)
+ .setIcon(ta.getDrawable(1))
.setEnabled(wifiIsEnabled)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menu.add(Menu.NONE, MENU_ID_ADD_NETWORK, 0, R.string.wifi_add_network)
@@ -458,11 +460,11 @@ public class WifiSettings extends RestrictedSettingsFragment
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
} else {
menu.add(Menu.NONE, MENU_ID_WPS_PBC, 0, R.string.wifi_menu_wps_pbc)
- .setIcon(R.drawable.ic_wps)
+ .setIcon(ta.getDrawable(1))
.setEnabled(wifiIsEnabled)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(Menu.NONE, MENU_ID_ADD_NETWORK, 0, R.string.wifi_add_network)
- .setIcon(R.drawable.ic_menu_add)
+ .setIcon(ta.getDrawable(0))
.setEnabled(wifiIsEnabled)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)
@@ -481,6 +483,7 @@ public class WifiSettings extends RestrictedSettingsFragment
//.setIcon(android.R.drawable.ic_menu_manage)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
+ ta.recycle();
super.onCreateOptionsMenu(menu, inflater);
}
@@ -808,7 +811,7 @@ public class WifiSettings extends RestrictedSettingsFragment
/** A restricted multimap for use in constructAccessPoints */
private class Multimap<K,V> {
- private HashMap<K,List<V>> store = new HashMap<K,List<V>>();
+ private final HashMap<K,List<V>> store = new HashMap<K,List<V>>();
/** retrieve a non-null list of values with key K */
List<V> getAll(K key) {
List<V> values = store.get(key);
diff --git a/src/com/android/settings/wifi/WifiSetupActivity.java b/src/com/android/settings/wifi/WifiSetupActivity.java
index 8415954..1739750 100644
--- a/src/com/android/settings/wifi/WifiSetupActivity.java
+++ b/src/com/android/settings/wifi/WifiSetupActivity.java
@@ -17,7 +17,25 @@ package com.android.settings.wifi;
import com.android.settings.ButtonBarHandler;
-// dummy class for setup wizard theme
+import android.content.res.Resources;
+
public class WifiSetupActivity extends WifiPickerActivity implements ButtonBarHandler {
+ // Extra containing the resource name of the theme to be used
+ private static final String EXTRA_THEME = "theme";
+ private static final String THEME_HOLO = "holo";
+ private static final String THEME_HOLO_LIGHT = "holo_light";
+
+ // Style resources containing theme settings
+ private static final String RESOURCE_THEME_DARK = "SetupWizardWifiTheme";
+ private static final String RESOURCE_THEME_LIGHT = "SetupWizardWifiTheme.Light";
-} \ No newline at end of file
+ @Override
+ protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
+ String themeName = getIntent().getStringExtra(EXTRA_THEME);
+ if (themeName != null && themeName.equalsIgnoreCase(THEME_HOLO_LIGHT)) {
+ resid = getResources().getIdentifier(RESOURCE_THEME_LIGHT, "style",
+ getPackageName());
+ }
+ super.onApplyThemeResource(theme, resid, first);
+ }
+}
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pPeer.java b/src/com/android/settings/wifi/p2p/WifiP2pPeer.java
index 1eb810e..a364021 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pPeer.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pPeer.java
@@ -20,21 +20,18 @@ import com.android.settings.R;
import android.content.Context;
import android.net.wifi.WifiManager;
-import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pDevice;
import android.preference.Preference;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
-import java.util.Comparator;
-
public class WifiP2pPeer extends Preference {
private static final int[] STATE_SECURED = {R.attr.state_encrypted};
public WifiP2pDevice device;
- private int mRssi;
+ private final int mRssi;
private ImageView mSignal;
private static final int SIGNAL_LEVELS = 4;
@@ -57,7 +54,7 @@ public class WifiP2pPeer extends Preference {
if (mRssi == Integer.MAX_VALUE) {
mSignal.setImageDrawable(null);
} else {
- mSignal.setImageResource(R.drawable.wifi_signal);
+ mSignal.setImageResource(R.drawable.wifi_signal_dark);
mSignal.setImageState(STATE_SECURED, true);
}
refresh();