Cancelling is not an immediate operation, since the load is performed
+ * in a background thread. If there is currently a load in progress, this
+ * method requests that the load be cancelled, and notes this is the case;
+ * once the background thread has completed its work its remaining state
+ * will be cleared. If another load request comes in during this time,
+ * it will be held until the cancelled load is complete.
+ *
+ * @return Returns false if the task could not be cancelled,
* typically because it has already completed normally, or
- * because {@link #startLoading()} hasn't been called, and
- * true otherwise
+ * because {@link #startLoading()} hasn't been called; returns
+ * true otherwise.
*/
public boolean cancelLoad() {
if (mTask != null) {
- boolean cancelled = mTask.cancel(false);
- mTask = null;
- return cancelled;
+ if (mCancellingTask != null) {
+ // There was a pending task already waiting for a previous
+ // one being canceled; just drop it.
+ if (mTask.waiting) {
+ mTask.waiting = false;
+ mHandler.removeCallbacks(mTask);
+ }
+ mTask = null;
+ return false;
+ } else if (mTask.waiting) {
+ // There is a task, but it is waiting for the time it should
+ // execute. We can just toss it.
+ mTask.waiting = false;
+ mHandler.removeCallbacks(mTask);
+ mTask = null;
+ return false;
+ } else {
+ boolean cancelled = mTask.cancel(false);
+ if (cancelled) {
+ mCancellingTask = mTask;
+ }
+ mTask = null;
+ return cancelled;
+ }
}
return false;
}
@@ -92,32 +151,67 @@ public abstract class AsyncTaskLoader
- * Used for testing.
+ * Use for testing only. Never call this from a UI thread.
*/
public void waitForLoader() {
LoadTask task = mTask;
@@ -132,4 +226,25 @@ public abstract class AsyncTaskLoader Note on threading: Clients of loaders should as a rule perform
+ * any calls on to a Loader from the main thread of their process (that is,
+ * the thread the Activity callbacks and other things occur on). Subclasses
+ * of Loader (such as {@link AsyncTaskLoader}) will often perform their work
+ * in a separate thread, but when delivering their results this too should
+ * be done on the main thread. Subclasses generally must implement at least {@link #onStartLoading()},
* {@link #onStopLoading()}, {@link #onForceLoad()}, and {@link #onReset()}.
*
@@ -80,7 +87,7 @@ public class Loader Must be called from the process's main thread.
*/
public void registerListener(int id, OnLoadCompleteListener This updates the Loader's internal state so that
* {@link #isStarted()} and {@link #isReset()} will return the correct
* values, and then calls the implementation's {@link #onStartLoading()}.
*
- * Must be called from the UI thread.
+ * Must be called from the process's main thread.
*/
public final void startLoading() {
mStarted = true;
@@ -182,14 +194,15 @@ public class Loader Must be called from the UI thread.
+ * Must be called from the process's main thread.
*/
- public final void forceLoad() {
+ public void forceLoad() {
onForceLoad();
}
/**
* Subclasses must implement this to take care of requests to {@link #forceLoad()}.
+ * This will always be called from the process's main thread.
*/
protected void onForceLoad() {
}
@@ -206,9 +219,9 @@ public class Loader Must be called from the UI thread.
+ * Must be called from the process's main thread.
*/
- public final void stopLoading() {
+ public void stopLoading() {
mStarted = false;
onStopLoading();
}
@@ -217,6 +230,7 @@ public class Loader Must be called from the UI thread.
+ * Must be called from the process's main thread.
*/
- public final void reset() {
+ public void reset() {
onReset();
mReset = true;
mStarted = false;
@@ -244,6 +258,7 @@ public class Loader Must be called from the UI thread.
+ * Must be called from the process's main thread.
*/
public void onContentChanged() {
if (mStarted) {
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 70a7fb66df265..f428aad71229f 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -311,7 +311,6 @@ public class DatabaseUtils {
/**
* Concatenates two SQL WHERE clauses, handling empty or null values.
- * @hide
*/
public static String concatenateWhere(String a, String b) {
if (TextUtils.isEmpty(a)) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 873674d27f4cf..cec99e96b7beb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3244,14 +3244,24 @@ public final class Settings {
/**
* Minimum percentage of free storage on the device that is used to determine if
- * the device is running low on storage.
- * Say this value is set to 10, the device is considered running low on storage
+ * the device is running low on storage. The default is 10.
+ * Say this value is set to 10, the device is considered running low on storage
* if 90% or more of the device storage is filled up.
* @hide
*/
public static final String SYS_STORAGE_THRESHOLD_PERCENTAGE =
"sys_storage_threshold_percentage";
+ /**
+ * Maximum byte size of the low storage threshold. This is to ensure
+ * that {@link #SYS_STORAGE_THRESHOLD_PERCENTAGE} does not result in
+ * an overly large threshold for large storage devices. Currently this
+ * must be less than 2GB. This default is 500MB.
+ * @hide
+ */
+ public static final String SYS_STORAGE_THRESHOLD_MAX_BYTES =
+ "sys_storage_threshold_max_bytes";
+
/**
* Minimum bytes of free storage on the device before the data
* partition is considered full. By default, 1 MB is reserved
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index ae938e77055b8..be4152bcc3f2f 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -51,6 +51,12 @@ public class ContextThemeWrapper extends ContextWrapper {
initializeTheme();
}
+ /** @hide */
+ @Override
+ public int getThemeResId() {
+ return mThemeResource;
+ }
+
@Override public Resources.Theme getTheme() {
if (mTheme != null) {
return mTheme;
diff --git a/docs/html/guide/topics/fragments/index.jd b/docs/html/guide/topics/fragments/index.jd
index 766146eb21c21..d07daf47a2d58 100644
--- a/docs/html/guide/topics/fragments/index.jd
+++ b/docs/html/guide/topics/fragments/index.jd
@@ -277,13 +277,13 @@ fragments to your activity layout. You simply need to specify a {@link android.v
which to place the fragment. To make any fragment transactions in your activity (such as add, remove, or replace a
fragment), you must use APIs from {@link android.app.FragmentTransaction}. You can get an instance
-of {@link android.app.FragmentTransaction} from your {@link android.app.Activity} using {@link
-android.app.Activity#openFragmentTransaction()}. You can then add a fragment using the {@link
+of {@link android.app.FragmentTransaction} from your {@link android.app.FragmentManager} using {@link
+android.app.FragmentManager#openTransaction()}. You can then add a fragment using the {@link
android.app.FragmentTransaction#add add()} method, specifying the fragment to add and the view in
which to insert it. For example: The first argument passed to {@link android.app.FragmentTransaction#add add()}
is the {@link android.view.ViewGroup} in which the fragment should be placed, specified by
@@ -372,8 +372,8 @@ android.app.Fragment#onStop onStop()} and others that coincide with the fragment
operations on a fragment as the user interacts with the activity, alowing for more rich user
experiences without changing activities. In order to perform these operations, you must use {@link
android.app.FragmentTransaction} to perform fragment "transactions." You can acquire {@link
-android.app.FragmentTransaction} from your activity with {@link
-android.app.Activity#openFragmentTransaction}. Common transactions you can perform with fragments include: Likewise, your activity can call public methods in the fragment when you have a reference to the
{@link android.app.Fragment}. You can acquire a reference to the fragment with {@link
-android.app.Activity#findFragmentById findFragmentById()} and cast it to your implementation of
+android.app.FragmentManager#findFragmentById findFragmentById()} and cast it to your implementation of
{@link android.app.Fragment}. For example:
MyFragment fragment = new MyFragment();
-openFragmentTransaction().add(R.id.fragment_container, fragment).commit();
+getFragmentManager().openTransaction().add(R.id.fragment_container, fragment).commit();
// Create new fragment
Fragment newFragment = new MyFragment();
-FragmentTransaction ft = openFragmentTransaction();
+FragmentTransaction ft = getFragmentManager().openTransaction();
// Replace and add to back stack
ft.replace(R.id.myfragment, newFragment);
ft.addToBackStack(null);
@@ -519,7 +519,7 @@ View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Ac
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 5ad0edb97fe9a..3e8318ed17869 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -34,6 +34,7 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.LocalPowerManager;
@@ -1017,23 +1018,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
try {
Context context = mContext;
- boolean setTheme = false;
//Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel="
// + nonLocalizedLabel + " theme=" + Integer.toHexString(theme));
- if (theme != 0 || labelRes != 0) {
+ if (theme != context.getThemeResId() || labelRes != 0) {
try {
context = context.createPackageContext(packageName, 0);
- if (theme != 0) {
- context.setTheme(theme);
- setTheme = true;
- }
+ context.setTheme(theme);
} catch (PackageManager.NameNotFoundException e) {
// Ignore
}
}
- if (!setTheme) {
- context.setTheme(com.android.internal.R.style.Theme);
- }
Window win = PolicyManager.makeNewWindow(context);
if (win.getWindowStyle().getBoolean(
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 0b1a4a3ee314c..0fba7c3603af0 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -16,7 +16,6 @@
package com.android.server;
-import com.android.server.am.ActivityManagerService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -38,7 +37,6 @@ import android.provider.Settings;
import android.util.Config;
import android.util.EventLog;
import android.util.Slog;
-import android.provider.Settings;
/**
* This class implements a service to monitor the amount of disk
@@ -66,6 +64,7 @@ class DeviceStorageMonitorService extends Binder {
private static final int MONITOR_INTERVAL = 1; //in minutes
private static final int LOW_MEMORY_NOTIFICATION_ID = 1;
private static final int DEFAULT_THRESHOLD_PERCENTAGE = 10;
+ private static final int DEFAULT_THRESHOLD_MAX_BYTES = 500*1024*1024; // 500MB
private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes
private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
@@ -271,13 +270,18 @@ class DeviceStorageMonitorService extends Binder {
* any way
*/
private long getMemThreshold() {
- int value = Settings.Secure.getInt(
+ long value = Settings.Secure.getInt(
mContentResolver,
Settings.Secure.SYS_STORAGE_THRESHOLD_PERCENTAGE,
DEFAULT_THRESHOLD_PERCENTAGE);
if(localLOGV) Slog.v(TAG, "Threshold Percentage="+value);
+ value *= mTotalMemory;
+ long maxValue = Settings.Secure.getInt(
+ mContentResolver,
+ Settings.Secure.SYS_STORAGE_THRESHOLD_MAX_BYTES,
+ DEFAULT_THRESHOLD_MAX_BYTES);
//evaluate threshold value
- return mTotalMemory*value;
+ return value < maxValue ? value : maxValue;
}
/*
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f1d548923f064..3c8fb017e9a3b 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1324,6 +1324,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ActivityThread at = ActivityThread.systemMain();
mSystemThread = at;
Context context = at.getSystemContext();
+ context.setTheme(android.R.style.Theme_Holo);
m.mContext = context;
m.mFactoryTest = factoryTest;
m.mMainStack = new ActivityStack(m, context, true);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index caaae1fb34282..72ea7ce84122f 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -26,6 +26,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.os.Process;
@@ -69,6 +70,7 @@ class ActivityRecord extends IApplicationToken.Stub {
int labelRes; // the label information from the package mgr.
int icon; // resource identifier of activity's icon.
int theme; // resource identifier of activity's theme.
+ int realTheme; // actual theme resource we will use, never 0.
int windowFlags; // custom window flags for preview window.
TaskRecord task; // the task this is in.
long launchTime; // when we starting launching this activity
@@ -246,6 +248,13 @@ class ActivityRecord extends IApplicationToken.Stub {
}
icon = aInfo.getIconResource();
theme = aInfo.getThemeResource();
+ realTheme = theme;
+ if (realTheme == 0) {
+ realTheme = aInfo.applicationInfo.targetSdkVersion
+ < Build.VERSION_CODES.HONEYCOMB
+ ? android.R.style.Theme
+ : android.R.style.Theme_Holo;
+ }
if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
@@ -266,8 +275,7 @@ class ActivityRecord extends IApplicationToken.Stub {
launchMode = aInfo.launchMode;
AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
- theme != 0 ? theme : android.R.style.Theme,
- com.android.internal.R.styleable.Window);
+ realTheme, com.android.internal.R.styleable.Window);
fullscreen = ent != null && !ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsFloating, false)
&& !ent.array.getBoolean(