summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml97
-rw-r--r--core/java/android/app/Activity.java36
-rw-r--r--core/java/android/app/ContextImpl.java5
-rw-r--r--core/java/android/app/DialogFragment.java2
-rw-r--r--core/java/android/app/FragmentTransaction.java8
-rw-r--r--core/java/android/content/AsyncTaskLoader.java153
-rw-r--r--core/java/android/content/Context.java6
-rw-r--r--core/java/android/content/ContextWrapper.java6
-rw-r--r--core/java/android/content/CursorLoader.java2
-rw-r--r--core/java/android/content/Loader.java51
-rw-r--r--core/java/android/database/DatabaseUtils.java1
-rw-r--r--core/java/android/provider/Settings.java14
-rw-r--r--core/java/android/view/ContextThemeWrapper.java6
-rw-r--r--docs/html/guide/topics/fragments/index.jd14
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java12
-rw-r--r--services/java/com/android/server/DeviceStorageMonitorService.java12
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java1
-rw-r--r--services/java/com/android/server/am/ActivityRecord.java12
18 files changed, 279 insertions, 159 deletions
diff --git a/api/current.xml b/api/current.xml
index 53f7f1e..7e81eb7 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -22817,32 +22817,6 @@
<parameter name="args" type="java.lang.String[]">
</parameter>
</method>
-<method name="findFragmentById"
- return="android.app.Fragment"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="id" type="int">
-</parameter>
-</method>
-<method name="findFragmentByTag"
- return="android.app.Fragment"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="tag" type="java.lang.String">
-</parameter>
-</method>
<method name="findViewById"
return="android.view.View"
abstract="false"
@@ -24065,17 +24039,6 @@
<parameter name="view" type="android.view.View">
</parameter>
</method>
-<method name="openFragmentTransaction"
- return="android.app.FragmentTransaction"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="openOptionsMenu"
return="void"
abstract="false"
@@ -43623,6 +43586,30 @@
<parameter name="data" type="D">
</parameter>
</method>
+<method name="onLoadInBackground"
+ return="D"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+</method>
+<method name="setUpdateThrottle"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="delayMS" type="long">
+</parameter>
+</method>
<method name="waitForLoader"
return="void"
abstract="false"
@@ -50212,21 +50199,6 @@
<parameter name="cursor" type="android.database.Cursor">
</parameter>
</method>
-<method name="registerContentObserver"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="cursor" type="android.database.Cursor">
-</parameter>
-<parameter name="observer" type="android.database.ContentObserver">
-</parameter>
-</method>
<method name="setProjection"
return="void"
abstract="false"
@@ -55453,7 +55425,7 @@
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -55578,7 +55550,7 @@
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -55600,7 +55572,7 @@
native="false"
synchronized="false"
static="false"
- final="true"
+ final="false"
deprecated="not deprecated"
visibility="public"
>
@@ -68017,6 +67989,21 @@
<parameter name="selectionArgs" type="java.lang.String[]">
</parameter>
</method>
+<method name="concatenateWhere"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="a" type="java.lang.String">
+</parameter>
+<parameter name="b" type="java.lang.String">
+</parameter>
+</method>
<method name="createDbFromSqlStatements"
return="void"
abstract="false"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 938c47d..ec2f771 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -73,13 +73,11 @@ import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
-import android.widget.FrameLayout;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
/**
* An activity is a single, focused thing that the user can do. Almost all
@@ -1579,16 +1577,6 @@ public class Activity extends ContextThemeWrapper
return mFragments;
}
- /**
- * Start a series of edit operations on the Fragments associated with
- * this activity.
- * @deprecated use {@link #getFragmentManager}.
- */
- @Deprecated
- public FragmentTransaction openFragmentTransaction() {
- return mFragments.openTransaction();
- }
-
void invalidateFragmentIndex(int index) {
//Log.v(TAG, "invalidateFragmentIndex: index=" + index);
if (mAllLoaderManagers != null) {
@@ -1770,30 +1758,6 @@ public class Activity extends ContextThemeWrapper
}
/**
- * Finds a fragment that was identified by the given id either when inflated
- * from XML or as the container ID when added in a transaction. This only
- * returns fragments that are currently added to the activity's content.
- * @return The fragment if found or null otherwise.
- * @deprecated use {@link #getFragmentManager}.
- */
- @Deprecated
- public Fragment findFragmentById(int id) {
- return mFragments.findFragmentById(id);
- }
-
- /**
- * Finds a fragment that was identified by the given tag either when inflated
- * from XML or as supplied when added in a transaction. This only
- * returns fragments that are currently added to the activity's content.
- * @return The fragment if found or null otherwise.
- * @deprecated use {@link #getFragmentManager}.
- */
- @Deprecated
- public Fragment findFragmentByTag(String tag) {
- return mFragments.findFragmentByTag(tag);
- }
-
- /**
* Set the activity content from a layout resource. The resource will be
* inflated, adding all top-level views to the activity.
*
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 72f7286..16d3a7f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -485,6 +485,11 @@ class ContextImpl extends Context {
}
@Override
+ public int getThemeResId() {
+ return mThemeResource;
+ }
+
+ @Override
public Resources.Theme getTheme() {
if (mTheme == null) {
if (mThemeResource == 0) {
diff --git a/core/java/android/app/DialogFragment.java b/core/java/android/app/DialogFragment.java
index bcd46d9..72a455e 100644
--- a/core/java/android/app/DialogFragment.java
+++ b/core/java/android/app/DialogFragment.java
@@ -211,7 +211,7 @@ public class DialogFragment extends Fragment
*/
@Deprecated
public void show(Activity activity, String tag) {
- FragmentTransaction ft = activity.openFragmentTransaction();
+ FragmentTransaction ft = activity.getFragmentManager().openTransaction();
ft.add(this, tag);
ft.commit();
}
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 5aec348..1b8debc 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -24,8 +24,8 @@ public abstract class FragmentTransaction {
* @param fragment The fragment to be added. This fragment must not already
* be added to the activity.
* @param tag Optional tag name for the fragment, to later retrieve the
- * fragment with {@link Activity#findFragmentByTag(String)
- * Activity.findFragmentByTag(String)}.
+ * fragment with {@link FragmentManager#findFragmentByTag(String)
+ * FragmentManager.findFragmentByTag(String)}.
*
* @return Returns the same FragmentTransaction instance.
*/
@@ -47,8 +47,8 @@ public abstract class FragmentTransaction {
* to be replaced.
* @param fragment The new fragment to place in the container.
* @param tag Optional tag name for the fragment, to later retrieve the
- * fragment with {@link Activity#findFragmentByTag(String)
- * Activity.findFragmentByTag(String)}.
+ * fragment with {@link FragmentManager#findFragmentByTag(String)
+ * FragmentManager.findFragmentByTag(String)}.
*
* @return Returns the same FragmentTransaction instance.
*/
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index 01a2912..ec4e578 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -17,8 +17,13 @@
package android.content;
import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.SystemClock;
import android.util.Log;
+import android.util.TimeUtils;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.concurrent.ExecutionException;
/**
@@ -30,14 +35,15 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
private static final String TAG = "AsyncTaskLoader";
- final class LoadTask extends AsyncTask<Void, Void, D> {
+ final class LoadTask extends AsyncTask<Void, Void, D> implements Runnable {
- private D result;
+ D result;
+ boolean waiting;
/* Runs on a worker thread */
@Override
protected D doInBackground(Void... params) {
- result = AsyncTaskLoader.this.loadInBackground();
+ result = AsyncTaskLoader.this.onLoadInBackground();
return result;
}
@@ -49,38 +55,91 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
@Override
protected void onCancelled() {
- AsyncTaskLoader.this.onCancelled(result);
+ AsyncTaskLoader.this.dispatchOnCancelled(this, result);
+ }
+
+ @Override
+ public void run() {
+ waiting = false;
+ AsyncTaskLoader.this.executePendingTask();
}
}
volatile LoadTask mTask;
+ volatile LoadTask mCancellingTask;
+
+ long mUpdateThrottle;
+ long mLastLoadCompleteTime = -10000;
+ Handler mHandler;
public AsyncTaskLoader(Context context) {
super(context);
}
+ /**
+ * Set amount to throttle updates by. This is the minimum time from
+ * when the last {@link #onLoadInBackground()} call has completed until
+ * a new load is scheduled.
+ *
+ * @param delayMS Amount of delay, in milliseconds.
+ */
+ public void setUpdateThrottle(long delayMS) {
+ mUpdateThrottle = delayMS;
+ if (delayMS != 0) {
+ mHandler = new Handler();
+ }
+ }
+
@Override
protected void onForceLoad() {
super.onForceLoad();
cancelLoad();
mTask = new LoadTask();
- mTask.execute((Void[]) null);
+ executePendingTask();
}
/**
* Attempt to cancel the current load task. See {@link AsyncTask#cancel(boolean)}
- * for more info.
+ * for more info. Must be called on the main thread of the process.
+ *
+ * <p>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 <tt>false</tt> if the task could not be canceled,
+ * @return Returns <tt>false</tt> if the task could not be cancelled,
* typically because it has already completed normally, or
- * because {@link #startLoading()} hasn't been called, and
- * <tt>true</tt> otherwise
+ * because {@link #startLoading()} hasn't been called; returns
+ * <tt>true</tt> 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<D> extends Loader<D> {
public void onCancelled(D data) {
}
+ void executePendingTask() {
+ if (mCancellingTask == null && mTask != null) {
+ if (mTask.waiting) {
+ mTask.waiting = false;
+ mHandler.removeCallbacks(mTask);
+ }
+ if (mUpdateThrottle > 0) {
+ long now = SystemClock.uptimeMillis();
+ if (now < (mLastLoadCompleteTime+mUpdateThrottle)) {
+ // Not yet time to do another load.
+ mTask.waiting = true;
+ mHandler.postAtTime(mTask, mLastLoadCompleteTime+mUpdateThrottle);
+ return;
+ }
+ }
+ mTask.execute((Void[]) null);
+ }
+ }
+
+ void dispatchOnCancelled(LoadTask task, D data) {
+ onCancelled(data);
+ if (mCancellingTask == task) {
+ mLastLoadCompleteTime = SystemClock.uptimeMillis();
+ mCancellingTask = null;
+ executePendingTask();
+ }
+ }
+
void dispatchOnLoadComplete(LoadTask task, D data) {
if (mTask != task) {
- onCancelled(data);
+ dispatchOnCancelled(task, data);
} else {
+ mLastLoadCompleteTime = SystemClock.uptimeMillis();
mTask = null;
deliverResult(data);
}
}
/**
+ */
+ public abstract D loadInBackground();
+
+ /**
* Called on a worker thread to perform the actual load. Implementations should not deliver the
- * results directly, but should return them from this method, which will eventually end up
- * calling deliverResult on the UI thread. If implementations need to process
- * the results on the UI thread they may override deliverResult and do so
+ * result directly, but should return them from this method, which will eventually end up
+ * calling {@link #deliverResult} on the UI thread. If implementations need to process
+ * the results on the UI thread they may override {@link #deliverResult} and do so
* there.
*
- * @return the result of the load
+ * @return Implementations must return the result of their load operation.
*/
- public abstract D loadInBackground();
+ protected D onLoadInBackground() {
+ return loadInBackground();
+ }
/**
* Locks the current thread until the loader completes the current load
* operation. Returns immediately if there is no load operation running.
* Should not be called from the UI thread.
* <p>
- * Used for testing.
+ * Use for testing only. <b>Never</b> call this from a UI thread.
*/
public void waitForLoader() {
LoadTask task = mTask;
@@ -132,4 +226,25 @@ public abstract class AsyncTaskLoader<D> extends Loader<D> {
}
}
}
+
+ @Override
+ public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+ super.dump(prefix, fd, writer, args);
+ if (mTask != null) {
+ writer.print(prefix); writer.print("mTask="); writer.print(mTask);
+ writer.print(" waiting="); writer.println(mTask.waiting);
+ }
+ if (mCancellingTask != null) {
+ writer.print(prefix); writer.print("mCancellingTask="); writer.print(mCancellingTask);
+ writer.print(" waiting="); writer.println(mCancellingTask.waiting);
+ }
+ if (mUpdateThrottle != 0) {
+ writer.print(prefix); writer.print("mUpdateThrottle=");
+ TimeUtils.formatDuration(mUpdateThrottle, writer);
+ writer.print(" mLastLoadCompleteTime=");
+ TimeUtils.formatDuration(mLastLoadCompleteTime,
+ SystemClock.uptimeMillis(), writer);
+ writer.println();
+ }
+ }
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index b128d31..227df21 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -227,6 +227,12 @@ public abstract class Context {
*/
public abstract void setTheme(int resid);
+ /** @hide Needed for some internal implementation... not public because
+ * you can't assume this actually means anything. */
+ public int getThemeResId() {
+ return 0;
+ }
+
/**
* Return the Theme object associated with this Context.
*/
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index f8928e4..545144e 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -106,6 +106,12 @@ public class ContextWrapper extends Context {
mBase.setTheme(resid);
}
+ /** @hide */
+ @Override
+ public int getThemeResId() {
+ return mBase.getThemeResId();
+ }
+
@Override
public Resources.Theme getTheme() {
return mBase.getTheme();
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index 8ab0973..38ebaf2 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -55,7 +55,7 @@ public class CursorLoader extends AsyncTaskLoader<Cursor> {
* Registers an observer to get notifications from the content provider
* when the cursor needs to be refreshed.
*/
- public void registerContentObserver(Cursor cursor, ContentObserver observer) {
+ void registerContentObserver(Cursor cursor, ContentObserver observer) {
cursor.registerContentObserver(mObserver);
}
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index ef81fe4..d63fe69 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -28,6 +28,13 @@ import java.io.PrintWriter;
* they should monitor the source of their data and deliver new results when the contents
* change.
*
+ * <p><b>Note on threading:</b> 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.</p>
+ *
* <p>Subclasses generally must implement at least {@link #onStartLoading()},
* {@link #onStopLoading()}, {@link #onForceLoad()}, and {@link #onReset()}.
*
@@ -80,7 +87,7 @@ public class Loader<D> {
/**
* Sends the result of the load to the registered listener. Should only be called by subclasses.
*
- * Must be called from the UI thread.
+ * Must be called from the process's main thread.
*
* @param data the result of the load
*/
@@ -105,10 +112,11 @@ public class Loader<D> {
}
/**
- * Registers a class that will receive callbacks when a load is complete. The callbacks will
- * be called on the UI thread so it's safe to pass the results to widgets.
+ * Registers a class that will receive callbacks when a load is complete.
+ * The callback will be called on the process's main thread so it's safe to
+ * pass the results to widgets.
*
- * Must be called from the UI thread
+ * <p>Must be called from the process's main thread.
*/
public void registerListener(int id, OnLoadCompleteListener<D> listener) {
if (mListener != null) {
@@ -119,7 +127,9 @@ public class Loader<D> {
}
/**
- * Must be called from the UI thread
+ * Remove a listener that was previously added with {@link #registerListener}.
+ *
+ * Must be called from the process's main thread.
*/
public void unregisterListener(OnLoadCompleteListener<D> listener) {
if (mListener == null) {
@@ -150,17 +160,19 @@ public class Loader<D> {
}
/**
- * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
- * will be called on the UI thread. If a previous load has been completed and is still valid
- * the result may be passed to the callbacks immediately. The loader will monitor the source of
- * the data set and may deliver future callbacks if the source changes. Calling
- * {@link #stopLoading} will stop the delivery of callbacks.
+ * Starts an asynchronous load of the Loader's data. When the result
+ * is ready the callbacks will be called on the process's main thread.
+ * If a previous load has been completed and is still valid
+ * the result may be passed to the callbacks immediately.
+ * The loader will monitor the source of
+ * the data set and may deliver future callbacks if the source changes.
+ * Calling {@link #stopLoading} will stop the delivery of callbacks.
*
* <p>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()}.
*
- * <p>Must be called from the UI thread.
+ * <p>Must be called from the process's main thread.
*/
public final void startLoading() {
mStarted = true;
@@ -182,14 +194,15 @@ public class Loader<D> {
* implementation's {@link #onForceLoad()}. You generally should only call this
* when the loader is started -- that is, {@link #isStarted()} returns true.
*
- * <p>Must be called from the UI thread.
+ * <p>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<D> {
* {@link #isStarted()} will return the correct
* value, and then calls the implementation's {@link #onStopLoading()}.
*
- * <p>Must be called from the UI thread.
+ * <p>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<D> {
* Subclasses must implement this to take care of stopping their loader,
* as per {@link #stopLoading()}. This is not called by clients directly,
* but as a result of a call to {@link #stopLoading()}.
+ * This will always be called from the process's main thread.
*/
protected void onStopLoading() {
}
@@ -231,9 +245,9 @@ public class Loader<D> {
* {@link #isStarted()} and {@link #isReset()} will return the correct
* values, and then calls the implementation's {@link #onReset()}.
*
- * <p>Must be called from the UI thread.
+ * <p>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<D> {
* Subclasses must implement this to take care of resetting their loader,
* as per {@link #reset()}. This is not called by clients directly,
* but as a result of a call to {@link #reset()}.
+ * This will always be called from the process's main thread.
*/
protected void onReset() {
}
@@ -265,7 +280,7 @@ public class Loader<D> {
* if so, it simply calls {@link #forceLoad()}; otherwise, it sets a flag
* so that {@link #takeContentChanged()} returns true.
*
- * <p>Must be called from the UI thread.
+ * <p>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 70a7fb6..f428aad 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 873674d..cec99e9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3244,8 +3244,8 @@ 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.
+ * <p>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
*/
@@ -3253,6 +3253,16 @@ public final class Settings {
"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
* to avoid system-wide SQLite disk full exceptions.
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index ae938e7..be4152b 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 766146e..d07daf4 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.</p>
<p>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:</p>
<pre>
MyFragment fragment = new MyFragment();
-openFragmentTransaction().add(R.id.fragment_container, fragment).commit();
+getFragmentManager().openTransaction().add(R.id.fragment_container, fragment).commit();
</pre>
<p>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}.</p>
+android.app.FragmentTransaction} from your FragmentManager with {@link
+android.app.FragmentManager#openTransaction}.</p>
<p>Common transactions you can perform with fragments include:</p>
@@ -397,7 +397,7 @@ in the back stack:</p>
<pre>
// 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
<p>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:</p>
<pre>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 5ad0edb..3e8318e 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 0b1a4a3..0fba7c3 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 f1d5489..3c8fb01 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 caaae1f..72ea7ce 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(