diff options
Diffstat (limited to 'core/java')
36 files changed, 784 insertions, 221 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 4761f98..bf9e07d 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -66,10 +66,10 @@ public class AccessibilityServiceInfo implements Parcelable { * The event types an {@link AccessibilityService} is interested in. * * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED + * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED - * @see android.view.accessibility.AccessibilityEvent#TYPE_ACTIVITY_STARTED * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED */ @@ -115,7 +115,7 @@ public class AccessibilityServiceInfo implements Parcelable { return 0; } - public void writeToParcel(Parcel parcel, int flags) { + public void writeToParcel(Parcel parcel, int flagz) { parcel.writeInt(eventTypes); parcel.writeStringArray(packageNames); parcel.writeInt(feedbackType); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 56e44c8..13cc3ba 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1392,7 +1392,7 @@ public final class ActivityThread { r.startsNotResumed = notResumed; r.createdConfig = config; - synchronized (mRelaunchingActivities) { + synchronized (mPackages) { mRelaunchingActivities.add(r); } @@ -1523,8 +1523,11 @@ public final class ActivityThread { } public void scheduleConfigurationChanged(Configuration config) { - synchronized (mRelaunchingActivities) { - mPendingConfiguration = config; + synchronized (mPackages) { + if (mPendingConfiguration == null || + mPendingConfiguration.isOtherSeqNewer(config)) { + mPendingConfiguration = config; + } } queueOrSendMessage(H.CONFIGURATION_CHANGED, config); } @@ -2060,6 +2063,7 @@ public final class ActivityThread { = new HashMap<IBinder, Service>(); AppBindData mBoundApplication; Configuration mConfiguration; + Configuration mResConfiguration; Application mInitialApplication; final ArrayList<Application> mAllApplications = new ArrayList<Application>(); @@ -2073,14 +2077,6 @@ public final class ActivityThread { boolean mSystemThread = false; boolean mJitEnabled = false; - /** - * Activities that are enqueued to be relaunched. This list is accessed - * by multiple threads, so you must synchronize on it when accessing it. - */ - final ArrayList<ActivityRecord> mRelaunchingActivities - = new ArrayList<ActivityRecord>(); - Configuration mPendingConfiguration = null; - // These can be accessed by multiple threads; mPackages is the lock. // XXX For now we keep around information about all packages we have // seen, not removing entries from this map. @@ -2092,6 +2088,9 @@ public final class ActivityThread { DisplayMetrics mDisplayMetrics = null; HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources = new HashMap<ResourcesKey, WeakReference<Resources> >(); + final ArrayList<ActivityRecord> mRelaunchingActivities + = new ArrayList<ActivityRecord>(); + Configuration mPendingConfiguration = null; // The lock of mProviderMap protects the following variables. final HashMap<String, ProviderRecord> mProviderMap @@ -3555,7 +3554,7 @@ public final class ActivityThread { // First: make sure we have the most recent configuration and most // recent version of the activity, or skip it if some previous call // had taken a more recent version. - synchronized (mRelaunchingActivities) { + synchronized (mPackages) { int N = mRelaunchingActivities.size(); IBinder token = tmp.token; tmp = null; @@ -3585,8 +3584,12 @@ public final class ActivityThread { // assume that is really what we want regardless of what we // may have pending. if (mConfiguration == null - || mConfiguration.diff(tmp.createdConfig) != 0) { - changedConfig = tmp.createdConfig; + || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) + && mConfiguration.diff(tmp.createdConfig) != 0)) { + if (changedConfig == null + || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { + changedConfig = tmp.createdConfig; + } } } @@ -3761,62 +3764,81 @@ public final class ActivityThread { } } + final void applyConfigurationToResourcesLocked(Configuration config) { + if (mResConfiguration == null) { + mResConfiguration = new Configuration(); + } + if (!mResConfiguration.isOtherSeqNewer(config)) { + return; + } + mResConfiguration.updateFrom(config); + DisplayMetrics dm = getDisplayMetricsLocked(true); + + // set it for java, this also affects newly created Resources + if (config.locale != null) { + Locale.setDefault(config.locale); + } + + Resources.updateSystemConfiguration(config, dm); + + ContextImpl.ApplicationPackageManager.configurationChanged(); + //Log.i(TAG, "Configuration changed in " + currentPackageName()); + + Iterator<WeakReference<Resources>> it = + mActiveResources.values().iterator(); + //Iterator<Map.Entry<String, WeakReference<Resources>>> it = + // mActiveResources.entrySet().iterator(); + while (it.hasNext()) { + WeakReference<Resources> v = it.next(); + Resources r = v.get(); + if (r != null) { + r.updateConfiguration(config, dm); + //Log.i(TAG, "Updated app resources " + v.getKey() + // + " " + r + ": " + r.getConfiguration()); + } else { + //Log.i(TAG, "Removing old resources " + v.getKey()); + it.remove(); + } + } + } + final void handleConfigurationChanged(Configuration config) { - synchronized (mRelaunchingActivities) { + ArrayList<ComponentCallbacks> callbacks = null; + + synchronized (mPackages) { if (mPendingConfiguration != null) { - config = mPendingConfiguration; + if (!mPendingConfiguration.isOtherSeqNewer(config)) { + config = mPendingConfiguration; + } mPendingConfiguration = null; } - } - - ArrayList<ComponentCallbacks> callbacks - = new ArrayList<ComponentCallbacks>(); - if (DEBUG_CONFIGURATION) Log.v(TAG, "Handle configuration changed: " - + config); + if (config == null) { + return; + } + + if (DEBUG_CONFIGURATION) Log.v(TAG, "Handle configuration changed: " + + config); - synchronized(mPackages) { + applyConfigurationToResourcesLocked(config); + if (mConfiguration == null) { mConfiguration = new Configuration(); } - mConfiguration.updateFrom(config); - DisplayMetrics dm = getDisplayMetricsLocked(true); - - // set it for java, this also affects newly created Resources - if (config.locale != null) { - Locale.setDefault(config.locale); - } - - Resources.updateSystemConfiguration(config, dm); - - ContextImpl.ApplicationPackageManager.configurationChanged(); - //Log.i(TAG, "Configuration changed in " + currentPackageName()); - { - Iterator<WeakReference<Resources>> it = - mActiveResources.values().iterator(); - //Iterator<Map.Entry<String, WeakReference<Resources>>> it = - // mActiveResources.entrySet().iterator(); - while (it.hasNext()) { - WeakReference<Resources> v = it.next(); - Resources r = v.get(); - if (r != null) { - r.updateConfiguration(config, dm); - //Log.i(TAG, "Updated app resources " + v.getKey() - // + " " + r + ": " + r.getConfiguration()); - } else { - //Log.i(TAG, "Removing old resources " + v.getKey()); - it.remove(); - } - } + if (!mConfiguration.isOtherSeqNewer(config)) { + return; } + mConfiguration.updateFrom(config); callbacks = collectComponentCallbacksLocked(false, config); } - final int N = callbacks.size(); - for (int i=0; i<N; i++) { - performConfigurationChanged(callbacks.get(i), config); + if (callbacks != null) { + final int N = callbacks.size(); + for (int i=0; i<N; i++) { + performConfigurationChanged(callbacks.get(i), config); + } } } @@ -3856,7 +3878,7 @@ public final class ActivityThread { ArrayList<ComponentCallbacks> callbacks = new ArrayList<ComponentCallbacks>(); - synchronized(mPackages) { + synchronized (mPackages) { callbacks = collectComponentCallbacksLocked(true, null); } @@ -4348,6 +4370,25 @@ public final class ActivityThread { "Unable to instantiate Application():" + e.toString(), e); } } + + ViewRoot.addConfigCallback(new ComponentCallbacks() { + public void onConfigurationChanged(Configuration newConfig) { + synchronized (mPackages) { + if (mPendingConfiguration == null || + mPendingConfiguration.isOtherSeqNewer(newConfig)) { + mPendingConfiguration = newConfig; + + // We need to apply this change to the resources + // immediately, because upon returning the view + // hierarchy will be informed about it. + applyConfigurationToResourcesLocked(newConfig); + } + } + queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig); + } + public void onLowMemory() { + } + }); } private final void detach() diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index 52cdc74..ce5f1bf 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -1690,6 +1690,25 @@ public class SearchManager } /** + * Gets the name of the web search activity. + * + * @return The name of the default activity for web searches. This activity + * can be used to get web search suggestions. Returns {@code null} if + * there is no default web search activity. + * + * @hide + */ + public ComponentName getWebSearchActivity() { + ComponentName globalSearch = getGlobalSearchActivity(); + if (globalSearch == null) { + return null; + } + Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); + intent.setPackage(globalSearch.getPackageName()); + return intent.resolveActivity(mContext.getPackageManager()); + } + + /** * Similar to {@link #startSearch} but actually fires off the search query after invoking * the search dialog. Made available for testing purposes. * diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java index 8ec5bd4..6767332 100644 --- a/core/java/android/app/Service.java +++ b/core/java/android/app/Service.java @@ -56,6 +56,8 @@ import java.io.PrintWriter; * <li><a href="#ServiceLifecycle">Service Lifecycle</a> * <li><a href="#Permissions">Permissions</a> * <li><a href="#ProcessLifecycle">Process Lifecycle</a> + * <li><a href="#LocalServiceSample">Local Service Sample</a> + * <li><a href="#RemoteMessengerServiceSample">Remote Messenger Service Sample</a> * </ol> * * <a name="ServiceLifecycle"></a> @@ -166,6 +168,64 @@ import java.io.PrintWriter; * (such as an {@link android.app.Activity}) can, of course, increase the * importance of the overall * process beyond just the importance of the service itself. + * + * <a name="LocalServiceSample"></a> + * <h3>Local Service Sample</h3> + * + * <p>One of the most common uses of a Service is as a secondary component + * running alongside other parts of an application, in the same process as + * the rest of the components. All components of an .apk run in the same + * process unless explicitly stated otherwise, so this is a typical situation. + * + * <p>When used in this way, by assuming the + * components are in the same process, you can greatly simplify the interaction + * between them: clients of the service can simply cast the IBinder they + * receive from it to a concrete class published by the service. + * + * <p>An example of this use of a Service is shown here. First is the Service + * itself, publishing a custom class when bound: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/LocalService.java + * service} + * + * <p>With that done, one can now write client code that directly accesses the + * running service, such as: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.java + * bind} + * + * <a name="RemoteMessengerServiceSample"></a> + * <h3>Remote Messenger Service Sample</h3> + * + * <p>If you need to be able to write a Service that can perform complicated + * communication with clients in remote processes (beyond simply the use of + * {@link Context#startService(Intent) Context.startService} to send + * commands to it), then you can use the {@link android.os.Messenger} class + * instead of writing full AIDL files. + * + * <p>An example of a Service that uses Messenger as its client interface + * is shown here. First is the Service itself, publishing a Messenger to + * an internal Handler when bound: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.java + * service} + * + * <p>If we want to make this service run in a remote process (instead of the + * standard one for its .apk), we can use <code>android:process</code> in its + * manifest tag to specify one: + * + * {@sample development/samples/ApiDemos/AndroidManifest.xml remote_service_declaration} + * + * <p>Note that the name "remote" chosen here is arbitrary, and you can use + * other names if you want additional processes. The ':' prefix appends the + * name to your package's standard process name. + * + * <p>With that done, clients can now bind to the service and send messages + * to it. Note that this allows clients to register with it to receive + * messages back as well: + * + * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.java + * bind} */ public abstract class Service extends ContextWrapper implements ComponentCallbacks { private static final String TAG = "Service"; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index d31b25b..1b0437c 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1815,11 +1815,18 @@ public class Intent implements Parcelable, Cloneable { /** * Broadcast Action: A sticky broadcast indicating the phone was docked - * or undocked. Includes the extra - * field {@link #EXTRA_DOCK_STATE}, containing the current dock state. It also - * includes the boolean extra field {@link #EXTRA_CAR_MODE_ENABLED}, indicating - * the state of the car mode. - * This is intended for monitoring the current dock state. + * or undocked. + * + * <p>The intent will have the following extra values: + * <ul> + * <li><em>{@link #EXTRA_DOCK_STATE}</em> - the current dock + * state, which depends on the state of the car mode.</li> + * <li><em>{@link #EXTRA_PHYSICAL_DOCK_STATE}</em> - the physical dock + * state.</li> + * <li><em>{@link #EXTRA_CAR_MODE_ENABLED}</em> - a boolean indicating the + * state of the car mode.</li> + * </ul> + * <p>This is intended for monitoring the current dock state. * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK} * or {@link #CATEGORY_DESK_DOCK} instead. */ @@ -2154,6 +2161,16 @@ public class Intent implements Parcelable, Cloneable { public static final int EXTRA_DOCK_STATE_CAR = 2; /** + * Used as an int extra field in {@link android.content.Intent#ACTION_DOCK_EVENT} + * intents to request the physical dock state. Possible values are + * {@link android.content.Intent#EXTRA_DOCK_STATE_UNDOCKED}, + * {@link android.content.Intent#EXTRA_DOCK_STATE_DESK}, or + * {@link android.content.Intent#EXTRA_DOCK_STATE_CAR}. + */ + public static final String EXTRA_PHYSICAL_DOCK_STATE = + "android.intent.extra.PHYSICAL_DOCK_STATE"; + + /** * Used as an boolean extra field in {@link android.content.Intent#ACTION_DOCK_EVENT} * intents to indicate that the car mode is enabled or not. */ diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 9ff2e25..4ddb819 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -447,17 +447,6 @@ public class SyncManager implements OnAccountsUpdateListener { } /** - * Returns whether or not sync is enabled. Sync can be enabled by - * setting the system property "ro.config.sync" to the value "yes". - * This is normally done at boot time on builds that support sync. - * @return true if sync is enabled - */ - private boolean isSyncEnabled() { - // Require the precise value "yes" to discourage accidental activation. - return "yes".equals(SystemProperties.get("ro.config.sync")); - } - - /** * Initiate a sync. This can start a sync for all providers * (pass null to url, set onlyTicklable to false), only those * providers that are marked as ticklable (pass null to url, @@ -488,13 +477,6 @@ public class SyncManager implements OnAccountsUpdateListener { Bundle extras, long delay, boolean onlyThoseWithUnkownSyncableState) { boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE); - if (!isSyncEnabled()) { - if (isLoggable) { - Log.v(TAG, "not syncing because sync is disabled"); - } - return; - } - final boolean backgroundDataUsageAllowed = !mBootCompleted || getConnectivityManager().getBackgroundDataSetting(); @@ -922,9 +904,7 @@ public class SyncManager implements OnAccountsUpdateListener { protected void dump(FileDescriptor fd, PrintWriter pw) { StringBuilder sb = new StringBuilder(); dumpSyncState(pw, sb); - if (isSyncEnabled()) { - dumpSyncHistory(pw, sb); - } + dumpSyncHistory(pw, sb); pw.println(); pw.println("SyncAdapters:"); @@ -940,7 +920,6 @@ public class SyncManager implements OnAccountsUpdateListener { } protected void dumpSyncState(PrintWriter pw, StringBuilder sb) { - pw.print("sync enabled: "); pw.println(isSyncEnabled()); pw.print("data connected: "); pw.println(mDataConnectionIsConnected); pw.print("memory low: "); pw.println(mStorageIsLow); @@ -1456,11 +1435,6 @@ public class SyncManager implements OnAccountsUpdateListener { boolean backgroundDataUsageAllowed) { Account[] accounts = mAccounts; - // Sync is disabled, drop this operation. - if (!isSyncEnabled()) { - return false; - } - // skip the sync if the account of this operation no longer exists if (!ArrayUtils.contains(accounts, account)) { return false; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index ff2ed3d..8576de2 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1153,7 +1153,9 @@ public abstract class PackageManager { * * @return Returns a ResolveInfo containing the final activity intent that * was determined to be the best action. Returns null if no - * matching activity was found. + * matching activity was found. If multiple matching activities are + * found and there is no default set, returns a ResolveInfo + * containing something else, such as the activity resolver. * * @see #MATCH_DEFAULT_ONLY * @see #GET_INTENT_FILTERS diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index aa5f128..6490b65 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -193,6 +193,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration public int uiMode; /** + * @hide Internal book-keeping. + */ + public int seq; + + /** * Construct an invalid Configuration. You must call {@link #setToDefaults} * for this object to be valid. {@more} */ @@ -220,6 +225,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration orientation = o.orientation; screenLayout = o.screenLayout; uiMode = o.uiMode; + seq = o.seq; } public String toString() { @@ -250,6 +256,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration sb.append(screenLayout); sb.append(" uiMode="); sb.append(uiMode); + if (seq != 0) { + sb.append(" seq="); + sb.append(seq); + } sb.append('}'); return sb.toString(); } @@ -260,7 +270,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration public void setToDefaults() { fontScale = 1; mcc = mnc = 0; - locale = Locale.getDefault(); + locale = null; userSetLocale = false; touchscreen = TOUCHSCREEN_UNDEFINED; keyboard = KEYBOARD_UNDEFINED; @@ -271,6 +281,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration orientation = ORIENTATION_UNDEFINED; screenLayout = SCREENLAYOUT_SIZE_UNDEFINED; uiMode = UI_MODE_TYPE_NORMAL; + seq = 0; } /** {@hide} */ @@ -357,6 +368,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration uiMode = delta.uiMode; } + if (delta.seq != 0) { + seq = delta.seq; + } + return changed; } @@ -456,6 +471,35 @@ public final class Configuration implements Parcelable, Comparable<Configuration } /** + * @hide Return true if the sequence of 'other' is better than this. Assumes + * that 'this' is your current sequence and 'other' is a new one you have + * received some how and want to compare with what you have. + */ + public boolean isOtherSeqNewer(Configuration other) { + if (other == null) { + // Sanity check. + return false; + } + if (other.seq == 0) { + // If the other sequence is not specified, then we must assume + // it is newer since we don't know any better. + return true; + } + if (seq == 0) { + // If this sequence is not specified, then we also consider the + // other is better. Yes we have a preference for other. Sue us. + return true; + } + int diff = other.seq - seq; + if (diff > 0x10000) { + // If there has been a sufficiently large jump, assume the + // sequence has wrapped around. + return false; + } + return diff > 0; + } + + /** * Parcelable methods */ public int describeContents() { @@ -488,6 +532,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration dest.writeInt(orientation); dest.writeInt(screenLayout); dest.writeInt(uiMode); + dest.writeInt(seq); } public static final Parcelable.Creator<Configuration> CREATOR @@ -522,6 +567,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration orientation = source.readInt(); screenLayout = source.readInt(); uiMode = source.readInt(); + seq = source.readInt(); } public int compareTo(Configuration that) { diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index ae8e297..a5e39d4 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -39,6 +39,7 @@ import android.view.Display; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; +import java.util.Locale; /** * Class for accessing an application's resources. This sits on top of the @@ -1259,6 +1260,9 @@ public class Resources { if (config != null) { configChanges = mConfiguration.updateFrom(config); } + if (mConfiguration.locale == null) { + mConfiguration.locale = Locale.getDefault(); + } if (metrics != null) { mMetrics.setTo(metrics); mMetrics.updateMetrics(mCompatibilityInfo, diff --git a/core/java/android/database/sqlite/SQLiteClosable.java b/core/java/android/database/sqlite/SQLiteClosable.java index 7776520..e589f34 100644 --- a/core/java/android/database/sqlite/SQLiteClosable.java +++ b/core/java/android/database/sqlite/SQLiteClosable.java @@ -16,6 +16,8 @@ package android.database.sqlite; +import android.database.CursorWindow; + /** * An object create from a SQLiteDatabase that can be closed. */ @@ -29,9 +31,9 @@ public abstract class SQLiteClosable { synchronized(mLock) { if (mReferenceCount <= 0) { throw new IllegalStateException( - "attempt to acquire a reference on an already-closed SQLiteClosable obj."); + "attempt to acquire a reference on an already-closed " + getObjInfo()); } - mReferenceCount++; + mReferenceCount++; } } @@ -52,4 +54,24 @@ public abstract class SQLiteClosable { } } } + + private String getObjInfo() { + StringBuilder buff = new StringBuilder(); + buff.append(this.getClass().getName()); + buff.append(" Obj"); + buff.append(" ("); + if (this instanceof SQLiteDatabase) { + buff.append("database = "); + buff.append(((SQLiteDatabase)this).getPath()); + } else if (this instanceof SQLiteProgram || this instanceof SQLiteStatement || + this instanceof SQLiteQuery) { + buff.append("mSql = "); + buff.append(((SQLiteProgram)this).mSql); + } else if (this instanceof CursorWindow) { + buff.append("mStartPos = "); + buff.append(((CursorWindow)this).getStartPosition()); + } + buff.append(") "); + return buff.toString(); + } } diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java index 79527b4..eb85822 100644 --- a/core/java/android/database/sqlite/SQLiteCompiledSql.java +++ b/core/java/android/database/sqlite/SQLiteCompiledSql.java @@ -44,6 +44,9 @@ import android.util.Log; */ /* package */ int nStatement = 0; + /** when in cache and is in use, this member is set */ + private boolean mInUse = false; + /* package */ SQLiteCompiledSql(SQLiteDatabase db, String sql) { mDatabase = db; this.nHandle = db.mNativeHandle; @@ -92,6 +95,18 @@ import android.util.Log; } } + /* package */ synchronized boolean isInUse() { + return mInUse; + } + + /* package */ synchronized void acquire() { + mInUse = true; + } + + /* package */ synchronized void release() { + mInUse = false; + } + /** * Make sure that the native resource is cleaned up. */ diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java index 2d0aa39..2bb2f5d 100644 --- a/core/java/android/database/sqlite/SQLiteProgram.java +++ b/core/java/android/database/sqlite/SQLiteProgram.java @@ -58,32 +58,51 @@ public abstract class SQLiteProgram extends SQLiteClosable { // add it to the cache of compiled-sqls db.addToCompiledQueries(sql, mCompiledSql); + mCompiledSql.acquire(); + } else { + // it is already in compiled-sql cache. + if (mCompiledSql.isInUse()) { + // but the CompiledSql in cache is in use by some other SQLiteProgram object. + // we can't have two different SQLiteProgam objects can't share the same + // CompiledSql object. create a new one. + // finalize it when I am done with it in "this" object. + mCompiledSql = new SQLiteCompiledSql(db, sql); + } else { + // the CompiledSql in cache is NOT in use by any other SQLiteProgram object. + // it is safe to give it to this SQLIteProgram Object. + mCompiledSql.acquire(); + } } nStatement = mCompiledSql.nStatement; } @Override protected void onAllReferencesReleased() { - releaseCompiledSqlIfInCache(); + releaseCompiledSqlIfNotInCache(); mDatabase.releaseReference(); mDatabase.removeSQLiteClosable(this); } @Override protected void onAllReferencesReleasedFromContainer() { - releaseCompiledSqlIfInCache(); + releaseCompiledSqlIfNotInCache(); mDatabase.releaseReference(); } - private void releaseCompiledSqlIfInCache() { + private void releaseCompiledSqlIfNotInCache() { if (mCompiledSql == null) { return; } synchronized(mDatabase.mCompiledQueries) { if (!mDatabase.mCompiledQueries.containsValue(mCompiledSql)) { + // it is NOT in compiled-sql cache. i.e., responsibility of + // release this statement is on me. mCompiledSql.releaseSqlStatement(); mCompiledSql = null; // so that GC doesn't call finalize() on it nStatement = 0; + } else { + // it is in compiled-sql cache. reset its CompiledSql#mInUse flag + mCompiledSql.release(); } } } diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index c0bff66..6dba94d 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -26,7 +26,7 @@ import java.io.IOException; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; -import android.graphics.PixelFormat; +import android.graphics.ImageFormat; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -192,7 +192,7 @@ public class Camera { * The callback that delivers the preview frames. * * @param data The contents of the preview frame in the format defined - * by {@link android.graphics.PixelFormat}, which can be queried + * by {@link android.graphics.ImageFormat}, which can be queried * with {@link android.hardware.Camera.Parameters#getPreviewFormat()}. * If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)} * is never called, the default will be the YCbCr_420_SP @@ -276,7 +276,7 @@ public class Camera { * Adds a pre-allocated buffer to the callback buffer queue. * Preview width and height can be determined from getPreviewSize, and bitsPerPixel can be * found from from {@link android.hardware.Camera.Parameters#getPreviewFormat()} and - * {@link android.graphics.PixelFormat#getPixelFormatInfo(int, PixelFormat)} + * {@link android.graphics.ImageFormat#getBitsPerPixel(int)} * * Alternatively, a buffer from a previous callback may be passed in or used * to determine the size of new preview frame buffers. @@ -1086,15 +1086,15 @@ public class Camera { /** * Sets the image format for preview pictures. * <p>If this is never called, the default format will be - * {@link android.graphics.PixelFormat#YCbCr_420_SP}, which + * {@link android.graphics.ImageFormat#NV21}, which * uses the NV21 encoding format.</p> * * @param pixel_format the desired preview picture format, defined - * by one of the {@link android.graphics.PixelFormat} constants. - * (E.g., <var>PixelFormat.YCbCr_420_SP</var> (default), - * <var>PixelFormat.RGB_565</var>, or - * <var>PixelFormat.JPEG</var>) - * @see android.graphics.PixelFormat + * by one of the {@link android.graphics.ImageFormat} constants. + * (E.g., <var>ImageFormat.NV21</var> (default), + * <var>ImageFormat.RGB_565</var>, or + * <var>ImageFormat.JPEG</var>) + * @see android.graphics.ImageFormat */ public void setPreviewFormat(int pixel_format) { String s = cameraFormatForPixelFormat(pixel_format); @@ -1110,7 +1110,7 @@ public class Camera { * Returns the image format for preview pictures got from * {@link PreviewCallback}. * - * @return the {@link android.graphics.PixelFormat} int representing + * @return the {@link android.graphics.ImageFormat} int representing * the preview picture format. */ public int getPreviewFormat() { @@ -1128,7 +1128,7 @@ public class Camera { ArrayList<Integer> formats = new ArrayList<Integer>(); for (String s : split(str)) { int f = pixelFormatForCameraFormat(s); - if (f == PixelFormat.UNKNOWN) continue; + if (f == ImageFormat.UNKNOWN) continue; formats.add(f); } return formats; @@ -1171,10 +1171,10 @@ public class Camera { * Sets the image format for pictures. * * @param pixel_format the desired picture format - * (<var>PixelFormat.YCbCr_420_SP (NV21)</var>, - * <var>PixelFormat.RGB_565</var>, or - * <var>PixelFormat.JPEG</var>) - * @see android.graphics.PixelFormat + * (<var>ImageFormat.NV21</var>, + * <var>ImageFormat.RGB_565</var>, or + * <var>ImageFormat.JPEG</var>) + * @see android.graphics.ImageFormat */ public void setPictureFormat(int pixel_format) { String s = cameraFormatForPixelFormat(pixel_format); @@ -1189,7 +1189,7 @@ public class Camera { /** * Returns the image format for pictures. * - * @return the PixelFormat int representing the picture format + * @return the ImageFormat int representing the picture format */ public int getPictureFormat() { return pixelFormatForCameraFormat(get(KEY_PICTURE_FORMAT)); @@ -1198,7 +1198,7 @@ public class Camera { /** * Gets the supported picture formats. * - * @return a List of Integer objects (values are PixelFormat.XXX). This + * @return a List of Integer objects (values are ImageFormat.XXX). This * method will always return a list with at least one element. */ public List<Integer> getSupportedPictureFormats() { @@ -1206,7 +1206,7 @@ public class Camera { ArrayList<Integer> formats = new ArrayList<Integer>(); for (String s : split(str)) { int f = pixelFormatForCameraFormat(s); - if (f == PixelFormat.UNKNOWN) continue; + if (f == ImageFormat.UNKNOWN) continue; formats.add(f); } return formats; @@ -1214,35 +1214,35 @@ public class Camera { private String cameraFormatForPixelFormat(int pixel_format) { switch(pixel_format) { - case PixelFormat.YCbCr_422_SP: return PIXEL_FORMAT_YUV422SP; - case PixelFormat.YCbCr_420_SP: return PIXEL_FORMAT_YUV420SP; - case PixelFormat.YCbCr_422_I: return PIXEL_FORMAT_YUV422I; - case PixelFormat.RGB_565: return PIXEL_FORMAT_RGB565; - case PixelFormat.JPEG: return PIXEL_FORMAT_JPEG; - default: return null; + case ImageFormat.NV16: return PIXEL_FORMAT_YUV422SP; + case ImageFormat.NV21: return PIXEL_FORMAT_YUV420SP; + case ImageFormat.YUY2: return PIXEL_FORMAT_YUV422I; + case ImageFormat.RGB_565: return PIXEL_FORMAT_RGB565; + case ImageFormat.JPEG: return PIXEL_FORMAT_JPEG; + default: return null; } } private int pixelFormatForCameraFormat(String format) { if (format == null) - return PixelFormat.UNKNOWN; + return ImageFormat.UNKNOWN; if (format.equals(PIXEL_FORMAT_YUV422SP)) - return PixelFormat.YCbCr_422_SP; + return ImageFormat.NV16; if (format.equals(PIXEL_FORMAT_YUV420SP)) - return PixelFormat.YCbCr_420_SP; + return ImageFormat.NV21; if (format.equals(PIXEL_FORMAT_YUV422I)) - return PixelFormat.YCbCr_422_I; + return ImageFormat.YUY2; if (format.equals(PIXEL_FORMAT_RGB565)) - return PixelFormat.RGB_565; + return ImageFormat.RGB_565; if (format.equals(PIXEL_FORMAT_JPEG)) - return PixelFormat.JPEG; + return ImageFormat.JPEG; - return PixelFormat.UNKNOWN; + return ImageFormat.UNKNOWN; } /** diff --git a/core/java/android/os/HandlerThread.java b/core/java/android/os/HandlerThread.java index 65301e4..911439a 100644 --- a/core/java/android/os/HandlerThread.java +++ b/core/java/android/os/HandlerThread.java @@ -53,9 +53,9 @@ public class HandlerThread extends Thread { Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); - Process.setThreadPriority(mPriority); notifyAll(); } + Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index f48f45f..92041d8 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -148,4 +148,18 @@ interface INetworkManagementService */ void detachPppd(String tty); + /** + * Turn on USB RNDIS support - this will turn off thinks like adb/mass-storage + */ + void startUsbRNDIS(); + + /** + * Turn off USB RNDIS support + */ + void stopUsbRNDIS(); + + /** + * Check the status of USB RNDIS support + */ + boolean isUsbRNDISStarted(); } diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java index 4130109..476da1d 100644 --- a/core/java/android/os/Message.java +++ b/core/java/android/os/Message.java @@ -40,20 +40,36 @@ public final class Message implements Parcelable { */ public int what; - // Use these fields instead of using the class's Bundle if you can. - /** arg1 and arg2 are lower-cost alternatives to using {@link #setData(Bundle) setData()} - if you only need to store a few integer values. */ + /** + * arg1 and arg2 are lower-cost alternatives to using + * {@link #setData(Bundle) setData()} if you only need to store a + * few integer values. + */ public int arg1; - /** arg1 and arg2 are lower-cost alternatives to using {@link #setData(Bundle) setData()} - if you only need to store a few integer values.*/ + /** + * arg1 and arg2 are lower-cost alternatives to using + * {@link #setData(Bundle) setData()} if you only need to store a + * few integer values. + */ public int arg2; - /** An arbitrary object to send to the recipient. This must be null when - * sending messages across processes. */ + /** + * An arbitrary object to send to the recipient. When using + * {@link Messenger} to send the message across processes this can only + * be non-null if it contains a Parcelable of a framework class (not one + * implemented by the application). For other data transfer use + * {@link #setData}. + * + * <p>Note that Parcelable objects here are not supported prior to + * the {@link android.os.Build.VERSION_CODES#FROYO} release. + */ public Object obj; - /** Optional Messenger where replies to this message can be sent. + /** + * Optional Messenger where replies to this message can be sent. The + * semantics of exactly how this is used are up to the sender and + * receiver. */ public Messenger replyTo; @@ -278,14 +294,22 @@ public final class Message implements Parcelable { * the <em>target</em> {@link Handler} that is receiving this Message to * dispatch it. If * not set, the message will be dispatched to the receiving Handler's - * {@link Handler#handleMessage(Message Handler.handleMessage())}. */ + * {@link Handler#handleMessage(Message Handler.handleMessage())}. + */ public Runnable getCallback() { return callback; } /** * Obtains a Bundle of arbitrary data associated with this - * event, lazily creating it if necessary. Set this value by calling {@link #setData(Bundle)}. + * event, lazily creating it if necessary. Set this value by calling + * {@link #setData(Bundle)}. Note that when transferring data across + * processes via {@link Messenger}, you will need to set your ClassLoader + * on the Bundle via {@link Bundle#setClassLoader(ClassLoader) + * Bundle.setClassLoader()} so that it can instantiate your objects when + * you retrieve them. + * @see #peekData() + * @see #setData(Bundle) */ public Bundle getData() { if (data == null) { @@ -297,14 +321,21 @@ public final class Message implements Parcelable { /** * Like getData(), but does not lazily create the Bundle. A null - * is returned if the Bundle does not already exist. + * is returned if the Bundle does not already exist. See + * {@link #getData} for further information on this. + * @see #getData() + * @see #setData(Bundle) */ public Bundle peekData() { return data; } - /** Sets a Bundle of arbitrary data values. Use arg1 and arg1 members - * as a lower cost way to send a few simple integer values, if you can. */ + /** + * Sets a Bundle of arbitrary data values. Use arg1 and arg1 members + * as a lower cost way to send a few simple integer values, if you can. + * @see #getData() + * @see #peekData() + */ public void setData(Bundle data) { this.data = data; } @@ -381,13 +412,25 @@ public final class Message implements Parcelable { } public void writeToParcel(Parcel dest, int flags) { - if (obj != null || callback != null) { + if (callback != null) { throw new RuntimeException( - "Can't marshal objects across processes."); + "Can't marshal callbacks across processes."); } dest.writeInt(what); dest.writeInt(arg1); dest.writeInt(arg2); + if (obj != null) { + try { + Parcelable p = (Parcelable)obj; + dest.writeInt(1); + dest.writeParcelable(p, flags); + } catch (ClassCastException e) { + throw new RuntimeException( + "Can't marshal non-Parcelable objects across processes."); + } + } else { + dest.writeInt(0); + } dest.writeLong(when); dest.writeBundle(data); Messenger.writeMessengerOrNullToParcel(replyTo, dest); @@ -397,6 +440,9 @@ public final class Message implements Parcelable { what = source.readInt(); arg1 = source.readInt(); arg2 = source.readInt(); + if (source.readInt() != 0) { + obj = source.readParcelable(getClass().getClassLoader()); + } when = source.readLong(); data = source.readBundle(); replyTo = Messenger.readMessengerOrNullFromParcel(source); diff --git a/core/java/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl index 816baf3..79a6cfe 100644 --- a/core/java/android/os/storage/IMountService.aidl +++ b/core/java/android/os/storage/IMountService.aidl @@ -63,7 +63,7 @@ interface IMountService * Safely unmount external storage at given mount point. * Returns an int consistent with MountServiceResultCode */ - int unmountVolume(String mountPoint); + int unmountVolume(String mountPoint, boolean force); /** * Format external storage given a mount point. @@ -100,7 +100,7 @@ interface IMountService * NOTE: Ensure all references are released prior to deleting. * Returns an int consistent with MountServiceResultCode */ - int destroySecureContainer(String id); + int destroySecureContainer(String id, boolean force); /* * Mount a secure container with the specified key and owner UID. @@ -112,7 +112,7 @@ interface IMountService * Unount a secure container. * Returns an int consistent with MountServiceResultCode */ - int unmountSecureContainer(String id); + int unmountSecureContainer(String id, boolean force); /* * Returns true if the specified container is mounted diff --git a/core/java/android/os/storage/StorageResultCode.java b/core/java/android/os/storage/StorageResultCode.java index 249bacf..07d95df 100644 --- a/core/java/android/os/storage/StorageResultCode.java +++ b/core/java/android/os/storage/StorageResultCode.java @@ -64,4 +64,10 @@ public class StorageResultCode */ public static final int OperationFailedStorageMounted = -6; + /** + * Operation failed: Storage is busy. + * @see android.os.storage.StorageManager + */ + public static final int OperationFailedStorageBusy = -7; + } diff --git a/core/java/android/pim/RecurrenceSet.java b/core/java/android/pim/RecurrenceSet.java index bd7924a..5d09fb5 100644 --- a/core/java/android/pim/RecurrenceSet.java +++ b/core/java/android/pim/RecurrenceSet.java @@ -48,7 +48,8 @@ public class RecurrenceSet { * events table in the CalendarProvider. * @param values The values retrieved from the Events table. */ - public RecurrenceSet(ContentValues values) { + public RecurrenceSet(ContentValues values) + throws EventRecurrence.InvalidFormatException { String rruleStr = values.getAsString(Calendar.Events.RRULE); String rdateStr = values.getAsString(Calendar.Events.RDATE); String exruleStr = values.getAsString(Calendar.Events.EXRULE); @@ -65,7 +66,8 @@ public class RecurrenceSet { * @param cursor The cursor containing the RRULE, RDATE, EXRULE, and EXDATE * columns. */ - public RecurrenceSet(Cursor cursor) { + public RecurrenceSet(Cursor cursor) + throws EventRecurrence.InvalidFormatException { int rruleColumn = cursor.getColumnIndex(Calendar.Events.RRULE); int rdateColumn = cursor.getColumnIndex(Calendar.Events.RDATE); int exruleColumn = cursor.getColumnIndex(Calendar.Events.EXRULE); @@ -78,12 +80,14 @@ public class RecurrenceSet { } public RecurrenceSet(String rruleStr, String rdateStr, - String exruleStr, String exdateStr) { + String exruleStr, String exdateStr) + throws EventRecurrence.InvalidFormatException { init(rruleStr, rdateStr, exruleStr, exdateStr); } private void init(String rruleStr, String rdateStr, - String exruleStr, String exdateStr) { + String exruleStr, String exdateStr) + throws EventRecurrence.InvalidFormatException { if (!TextUtils.isEmpty(rruleStr) || !TextUtils.isEmpty(rdateStr)) { if (!TextUtils.isEmpty(rruleStr)) { diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index eb48a0c..52de64c 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -28,6 +28,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; @@ -226,7 +227,7 @@ public abstract class WallpaperService extends Service { @Override public void resized(int w, int h, Rect coveredInsets, - Rect visibleInsets, boolean reportDraw) { + Rect visibleInsets, boolean reportDraw, Configuration newConfig) { Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0); mCaller.sendMessage(msg); diff --git a/core/java/android/speech/RecognitionManager.java b/core/java/android/speech/RecognitionManager.java index 7f55ad6..16b1f89 100644 --- a/core/java/android/speech/RecognitionManager.java +++ b/core/java/android/speech/RecognitionManager.java @@ -98,6 +98,9 @@ public class RecognitionManager { /** Context with which the manager was created */ private final Context mContext; + + /** Component to direct service intent to */ + private final ComponentName mServiceComponent; /** Handler that will execute the main tasks */ private Handler mHandler = new Handler() { @@ -133,8 +136,9 @@ public class RecognitionManager { * The right way to create a {@code RecognitionManager} is by using * {@link #createRecognitionManager} static factory method */ - private RecognitionManager(final Context context) { + private RecognitionManager(final Context context, final ComponentName serviceComponent) { mContext = context; + mServiceComponent = serviceComponent; } /** @@ -184,11 +188,31 @@ public class RecognitionManager { * @return a new {@code RecognitionManager} */ public static RecognitionManager createRecognitionManager(final Context context) { + return createRecognitionManager(context, null); + } + + /** + * Factory method to create a new {@code RecognitionManager}, please note that + * {@link #setRecognitionListener(RecognitionListener)} must be called before dispatching any + * command to the created {@code RecognitionManager}. + * + * Use this version of the method to specify a specific service to direct this + * {@link RecognitionManager} to. Normally you would not use this; use + * {@link #createRecognitionManager(Context)} instead to use the system default + * recognition service. + * + * @param context in which to create {@code RecognitionManager} + * @param serviceComponent the {@link ComponentName} of a specific service to direct this + * {@code RecognitionManager} to + * @return a new {@code RecognitionManager} + */ + public static RecognitionManager createRecognitionManager(final Context context, + final ComponentName serviceComponent) { if (context == null) { throw new IllegalArgumentException("Context cannot be null)"); } checkIsCalledFromMainThread(); - return new RecognitionManager(context); + return new RecognitionManager(context, serviceComponent); } /** @@ -222,17 +246,22 @@ public class RecognitionManager { mConnection = new Connection(); Intent serviceIntent = new Intent(RecognitionService.SERVICE_INTERFACE); - String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(), - Settings.Secure.VOICE_RECOGNITION_SERVICE); - if (TextUtils.isEmpty(serviceComponent)) { - Log.e(TAG, "no selected voice recognition service"); - mListener.onError(ERROR_CLIENT); - return; + if (mServiceComponent == null) { + String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.VOICE_RECOGNITION_SERVICE); + + if (TextUtils.isEmpty(serviceComponent)) { + Log.e(TAG, "no selected voice recognition service"); + mListener.onError(ERROR_CLIENT); + return; + } + + serviceIntent.setComponent(ComponentName.unflattenFromString(serviceComponent)); + } else { + serviceIntent.setComponent(mServiceComponent); } - serviceIntent.setComponent(ComponentName.unflattenFromString(serviceComponent)); - if (!mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) { Log.e(TAG, "bind to recognition service failed"); mConnection = null; diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java index 5f651e1..7c15cec 100644 --- a/core/java/android/speech/RecognizerIntent.java +++ b/core/java/android/speech/RecognizerIntent.java @@ -16,9 +16,17 @@ package android.speech; +import java.util.ArrayList; + import android.app.Activity; import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; /** * Constants for supporting speech recognition through starting an {@link Intent} @@ -208,4 +216,92 @@ public class RecognizerIntent { * an activity result. In a PendingIntent, the lack of this extra indicates failure. */ public static final String EXTRA_RESULTS = "android.speech.extra.RESULTS"; + + /** + * Returns the broadcast intent to fire with + * {@link Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)} + * to receive details from the package that implements voice search. + * <p> + * This is based on the value specified by the voice search {@link Activity} in + * {@link #DETAILS_META_DATA}, and if this is not specified, will return null. Also if there + * is no chosen default to resolve for {@link #ACTION_WEB_SEARCH}, this will return null. + * <p> + * If an intent is returned and is fired, a {@link Bundle} of extras will be returned to the + * provided result receiver, and should ideally contain values for + * {@link #EXTRA_LANGUAGE_PREFERENCE} and {@link #EXTRA_SUPPORTED_LANGUAGES}. + * <p> + * (Whether these are actually provided is up to the particular implementation. It is + * recommended that {@link Activity}s implementing {@link #ACTION_WEB_SEARCH} provide this + * information, but it is not required.) + * + * @param context a context object + * @return the broadcast intent to fire or null if not available + */ + public static final Intent getVoiceDetailsIntent(Context context) { + Intent voiceSearchIntent = new Intent(ACTION_WEB_SEARCH); + ResolveInfo ri = context.getPackageManager().resolveActivity( + voiceSearchIntent, PackageManager.GET_META_DATA); + if (ri == null || ri.activityInfo == null || ri.activityInfo.metaData == null) return null; + + String className = ri.activityInfo.metaData.getString(DETAILS_META_DATA); + if (className == null) return null; + + Intent detailsIntent = new Intent(ACTION_GET_LANGUAGE_DETAILS); + detailsIntent.setComponent(new ComponentName(ri.activityInfo.packageName, className)); + return detailsIntent; + } + + /** + * Meta-data name under which an {@link Activity} implementing {@link #ACTION_WEB_SEARCH} can + * use to expose the class name of a {@link BroadcastReceiver} which can respond to request for + * more information, from any of the broadcast intents specified in this class. + * <p> + * Broadcast intents can be directed to the class name specified in the meta-data by creating + * an {@link Intent}, setting the component with + * {@link Intent#setComponent(android.content.ComponentName)}, and using + * {@link Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle)} + * with another {@link BroadcastReceiver} which can receive the results. + * <p> + * The {@link #getVoiceDetailsIntent(Context)} method is provided as a convenience to create + * a broadcast intent based on the value of this meta-data, if available. + * <p> + * This is optional and not all {@link Activity}s which implement {@link #ACTION_WEB_SEARCH} + * are required to implement this. Thus retrieving this meta-data may be null. + */ + public static final String DETAILS_META_DATA = "android.speech.DETAILS"; + + /** + * A broadcast intent which can be fired to the {@link BroadcastReceiver} component specified + * in the meta-data defined in the {@link #DETAILS_META_DATA} meta-data of an + * {@link Activity} satisfying {@link #ACTION_WEB_SEARCH}. + * <p> + * When fired with + * {@link Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle)}, + * a {@link Bundle} of extras will be returned to the provided result receiver, and should + * ideally contain values for {@link #EXTRA_LANGUAGE_PREFERENCE} and + * {@link #EXTRA_SUPPORTED_LANGUAGES}. + * <p> + * (Whether these are actually provided is up to the particular implementation. It is + * recommended that {@link Activity}s implementing {@link #ACTION_WEB_SEARCH} provide this + * information, but it is not required.) + */ + public static final String ACTION_GET_LANGUAGE_DETAILS = + "android.speech.action.GET_LANGUAGE_DETAILS"; + + /** + * The key to the extra in the {@link Bundle} returned by {@link #ACTION_GET_LANGUAGE_DETAILS} + * which is a {@link String} that represents the current language preference this user has + * specified - a locale string like "en-US". + */ + public static final String EXTRA_LANGUAGE_PREFERENCE = + "android.speech.extra.LANGUAGE_PREFERENCE"; + + /** + * The key to the extra in the {@link Bundle} returned by {@link #ACTION_GET_LANGUAGE_DETAILS} + * which is an {@link ArrayList} of {@link String}s that represents the languages supported by + * this implementation of voice recognition - a list of strings like "en-US", "cmn-Hans-CN", + * etc. + */ + public static final String EXTRA_SUPPORTED_LANGUAGES = + "android.speech.extra.SUPPORTED_LANGUAGES"; } diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 71302cb..3b09808 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -17,6 +17,7 @@ package android.view; +import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; @@ -44,7 +45,7 @@ oneway interface IWindow { void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor); void resized(int w, int h, in Rect coveredInsets, in Rect visibleInsets, - boolean reportDraw); + boolean reportDraw, in Configuration newConfig); void dispatchKey(in KeyEvent event); void dispatchPointer(in MotionEvent event, long eventTime, boolean callWhenDone); void dispatchTrackball(in MotionEvent event, long eventTime, boolean callWhenDone); diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 0ebe360..9b7b2f4 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -64,8 +64,6 @@ interface IWindowManager void addAppToken(int addPos, IApplicationToken token, int groupId, int requestedOrientation, boolean fullscreen); void setAppGroupId(IBinder token, int groupId); - Configuration updateOrientationFromAppTokens(in Configuration currentConfig, - IBinder freezeThisOneIfNeeded); void setAppOrientation(IApplicationToken token, int requestedOrientation); int getAppOrientation(IApplicationToken token); void setFocusedApp(IBinder token, boolean moveFocusNow); @@ -85,6 +83,13 @@ interface IWindowManager void moveAppTokensToTop(in List<IBinder> tokens); void moveAppTokensToBottom(in List<IBinder> tokens); + // Re-evaluate the current orientation from the caller's state. + // If there is a change, the new Configuration is returned and the + // caller must call setNewConfiguration() sometime later. + Configuration updateOrientationFromAppTokens(in Configuration currentConfig, + IBinder freezeThisOneIfNeeded); + void setNewConfiguration(in Configuration config); + // these require DISABLE_KEYGUARD permission void disableKeyguard(IBinder token, String tag); void reenableKeyguard(IBinder token); diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index ca5e1de..d7f2539 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -19,6 +19,7 @@ package android.view; import com.android.internal.view.BaseIWindow; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.CompatibilityInfo.Translator; import android.graphics.Canvas; @@ -504,7 +505,7 @@ public class SurfaceView extends View { } public void resized(int w, int h, Rect coveredInsets, - Rect visibleInsets, boolean reportDraw) { + Rect visibleInsets, boolean reportDraw, Configuration newConfig) { SurfaceView surfaceView = mSurfaceView.get(); if (surfaceView != null) { if (localLOGV) Log.v( diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index bc49439..2eb633f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -20,6 +20,7 @@ import com.android.internal.R; import com.android.internal.view.menu.MenuBuilder; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; @@ -3933,6 +3934,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } /** + * Dispatch a notification about a resource configuration change down + * the view hierarchy. + * ViewGroups should override to route to their children. + * + * @param newConfig The new resource configuration. + * + * @see #onConfigurationChanged + */ + public void dispatchConfigurationChanged(Configuration newConfig) { + onConfigurationChanged(newConfig); + } + + /** + * Called when the current configuration of the resources being used + * by the application have changed. You can use this to decide when + * to reload resources that can changed based on orientation and other + * configuration characterstics. You only need to use this if you are + * not relying on the normal {@link android.app.Activity} mechanism of + * recreating the activity instance upon a configuration change. + * + * @param newConfig The new resource configuration. + */ + protected void onConfigurationChanged(Configuration newConfig) { + } + + /** * Private function to aggregate all per-view attributes in to the view * root. */ diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 2ed623d..0663215 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -19,6 +19,7 @@ package android.view; import com.android.internal.R; import android.content.Context; +import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -722,6 +723,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** * {@inheritDoc} */ + @Override + public void dispatchConfigurationChanged(Configuration newConfig) { + super.dispatchConfigurationChanged(newConfig); + final int count = mChildrenCount; + final View[] children = mChildren; + for (int i = 0; i < count; i++) { + children[i].dispatchConfigurationChanged(newConfig); + } + } + + /** + * {@inheritDoc} + */ public void recomputeViewAttributes(View child) { ViewParent parent = mParent; if (parent != null) parent.recomputeViewAttributes(this); diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 07b2d1c..264b8c9 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -41,7 +41,9 @@ import android.view.inputmethod.InputMethodManager; import android.widget.Scroller; import android.content.pm.PackageManager; import android.content.res.CompatibilityInfo; +import android.content.res.Configuration; import android.content.res.Resources; +import android.content.ComponentCallbacks; import android.content.Context; import android.app.ActivityManagerNative; import android.Manifest; @@ -101,6 +103,9 @@ public final class ViewRoot extends Handler implements ViewParent, static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList<Runnable>(); static boolean sFirstDrawComplete = false; + static final ArrayList<ComponentCallbacks> sConfigCallbacks + = new ArrayList<ComponentCallbacks>(); + private static int sDrawTime; long mLastTrackballTime = 0; @@ -171,6 +176,12 @@ public final class ViewRoot extends Handler implements ViewParent, final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets = new ViewTreeObserver.InternalInsetsInfo(); + class ResizedInfo { + Rect coveredInsets; + Rect visibleInsets; + Configuration newConfig; + } + boolean mScrollMayChange; int mSoftInputMode; View mLastScrolledFocus; @@ -265,6 +276,12 @@ public final class ViewRoot extends Handler implements ViewParent, } } + public static void addConfigCallback(ComponentCallbacks callback) { + synchronized (sConfigCallbacks) { + sConfigCallbacks.add(callback); + } + } + // FIXME for perf testing only private boolean mProfile = false; @@ -1782,23 +1799,33 @@ public final class ViewRoot extends Handler implements ViewParent, handleGetNewSurface(); break; case RESIZED: - Rect coveredInsets = ((Rect[])msg.obj)[0]; - Rect visibleInsets = ((Rect[])msg.obj)[1]; + ResizedInfo ri = (ResizedInfo)msg.obj; if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2 - && mPendingContentInsets.equals(coveredInsets) - && mPendingVisibleInsets.equals(visibleInsets)) { + && mPendingContentInsets.equals(ri.coveredInsets) + && mPendingVisibleInsets.equals(ri.visibleInsets)) { break; } // fall through... case RESIZED_REPORT: if (mAdded) { + Configuration config = ((ResizedInfo)msg.obj).newConfig; + if (config != null) { + synchronized (sConfigCallbacks) { + for (int i=sConfigCallbacks.size()-1; i>=0; i--) { + sConfigCallbacks.get(i).onConfigurationChanged(config); + } + } + if (mView != null) { + mView.dispatchConfigurationChanged(config); + } + } mWinFrame.left = 0; mWinFrame.right = msg.arg1; mWinFrame.top = 0; mWinFrame.bottom = msg.arg2; - mPendingContentInsets.set(((Rect[])msg.obj)[0]); - mPendingVisibleInsets.set(((Rect[])msg.obj)[1]); + mPendingContentInsets.set(((ResizedInfo)msg.obj).coveredInsets); + mPendingVisibleInsets.set(((ResizedInfo)msg.obj).visibleInsets); if (msg.what == RESIZED_REPORT) { mReportNextDraw = true; } @@ -2587,7 +2614,7 @@ public final class ViewRoot extends Handler implements ViewParent, } public void dispatchResized(int w, int h, Rect coveredInsets, - Rect visibleInsets, boolean reportDraw) { + Rect visibleInsets, boolean reportDraw, Configuration newConfig) { if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": w=" + w + " h=" + h + " coveredInsets=" + coveredInsets.toShortString() + " visibleInsets=" + visibleInsets.toShortString() @@ -2601,7 +2628,11 @@ public final class ViewRoot extends Handler implements ViewParent, } msg.arg1 = w; msg.arg2 = h; - msg.obj = new Rect[] { new Rect(coveredInsets), new Rect(visibleInsets) }; + ResizedInfo ri = new ResizedInfo(); + ri.coveredInsets = new Rect(coveredInsets); + ri.visibleInsets = new Rect(visibleInsets); + ri.newConfig = newConfig; + msg.obj = ri; sendMessage(msg); } @@ -2802,11 +2833,11 @@ public final class ViewRoot extends Handler implements ViewParent, } public void resized(int w, int h, Rect coveredInsets, - Rect visibleInsets, boolean reportDraw) { + Rect visibleInsets, boolean reportDraw, Configuration newConfig) { final ViewRoot viewRoot = mViewRoot.get(); if (viewRoot != null) { viewRoot.dispatchResized(w, h, coveredInsets, - visibleInsets, reportDraw); + visibleInsets, reportDraw, newConfig); } } diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java index 16feaa9..bc13504 100644 --- a/core/java/android/webkit/DateSorter.java +++ b/core/java/android/webkit/DateSorter.java @@ -26,7 +26,7 @@ import java.util.Date; * Sorts dates into the following groups: * Today * Yesterday - * five days ago + * seven days ago * one month ago * older than a month ago */ @@ -41,7 +41,7 @@ public class DateSorter { private long [] mBins = new long[DAY_COUNT-1]; private String [] mLabels = new String[DAY_COUNT]; - private static final int NUM_DAYS_AGO = 5; + private static final int NUM_DAYS_AGO = 7; /** * @param context Application context diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 39e5275..662be95 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -916,9 +916,12 @@ public class WebSettings { } /** - * Tell the WebView to block network image. This is only checked when - * getLoadsImagesAutomatically() is true. - * @param flag True if the WebView should block network image + * Tell the WebView to block network images. This is only checked when + * {@link #getLoadsImagesAutomatically} is true. If you set the value to + * false, images will automatically be loaded. Use this api to reduce + * bandwidth only. Use {@link #setBlockNetworkLoads} if possible. + * @param flag True if the WebView should block network images. + * @see #setBlockNetworkLoads */ public synchronized void setBlockNetworkImage(boolean flag) { if (mBlockNetworkImage != flag) { @@ -928,17 +931,21 @@ public class WebSettings { } /** - * Return true if the WebView will block network image. The default is false. - * @return True if the WebView blocks network image. + * Return true if the WebView will block network images. The default is + * false. + * @return True if the WebView blocks network images. */ public synchronized boolean getBlockNetworkImage() { return mBlockNetworkImage; } /** - * @hide - * Tell the WebView to block all network load requests. - * @param flag True if the WebView should block all network loads + * Tell the WebView to block all network load requests. If you set the + * value to false, you must call {@link android.webkit.WebView#reload} to + * fetch remote resources. This flag supercedes the value passed to + * {@link #setBlockNetworkImage}. + * @param flag True if the WebView should block all network loads. + * @see android.webkit.WebView#reload */ public synchronized void setBlockNetworkLoads(boolean flag) { if (mBlockNetworkLoads != flag) { @@ -948,9 +955,8 @@ public class WebSettings { } /** - * @hide - * Return true if the WebView will block all network loads. - * The default is false. + * Return true if the WebView will block all network loads. The default is + * false. * @return True if the WebView blocks all network loads. */ public synchronized boolean getBlockNetworkLoads() { diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 9672892..adae0cb 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -3088,14 +3088,11 @@ public class WebView extends AbsoluteLayout Rect vBox = contentToViewRect(contentBounds); Rect visibleRect = new Rect(); calcOurVisibleRect(visibleRect); - // The IME may have shown, resulting in the textfield being offscreen. - // If so, the textfield will be scrolled on screen, so treat it as - // though it is on screen. If it is on screen, place the WebTextView in - // its new place, accounting for our new scroll/zoom values. - InputMethodManager imm = InputMethodManager.peekInstance(); - if ((imm != null && imm.isActive(mWebTextView)) - || (allowIntersect ? Rect.intersects(visibleRect, vBox) - : visibleRect.contains(vBox))) { + // If the textfield is on screen, place the WebTextView in + // its new place, accounting for our new scroll/zoom values, + // and adjust its textsize. + if (allowIntersect ? Rect.intersects(visibleRect, vBox) + : visibleRect.contains(vBox)) { mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height()); mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, @@ -4439,6 +4436,7 @@ public class WebView extends AbsoluteLayout ted.mX = viewToContentX((int) x + mScrollX); ted.mY = viewToContentY((int) y + mScrollY); ted.mEventTime = eventTime; + ted.mMetaState = ev.getMetaState(); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); mLastSentTouchTime = eventTime; } @@ -4702,6 +4700,7 @@ public class WebView extends AbsoluteLayout ted.mX = viewToContentX((int) x + mScrollX); ted.mY = viewToContentY((int) y + mScrollY); ted.mEventTime = eventTime; + ted.mMetaState = ev.getMetaState(); mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); } else if (mFullScreenHolder == null) { doDoubleTap(); @@ -5738,6 +5737,11 @@ public class WebView extends AbsoluteLayout ted.mX = viewToContentX((int) mLastTouchX + mScrollX); ted.mY = viewToContentY((int) mLastTouchY + mScrollY); ted.mEventTime = SystemClock.uptimeMillis(); + // metaState for long press is tricky. Should it be the state + // when the press started or when the press was released? Or + // some intermediary key state? For simplicity for now, we + // don't set it. + ted.mMetaState = 0; mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted); } else if (mPreventDrag == PREVENT_DRAG_NO) { mTouchMode = TOUCH_DONE_MODE; diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 3a3e445..361ec56 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -515,7 +515,7 @@ final class WebViewCore { private native void nativeTouchUp(int touchGeneration, int framePtr, int nodePtr, int x, int y); - private native int nativeHandleTouchEvent(int action, int x, int y, long time); + private native int nativeHandleTouchEvent(int action, int x, int y, long time, int metaState); private native void nativeUpdateFrameCache(); @@ -735,6 +735,7 @@ final class WebViewCore { int mX; int mY; long mEventTime; + int mMetaState; } static class GeolocationPermissionsData { @@ -1198,7 +1199,7 @@ final class WebViewCore { mWebView.mPrivateHandler, WebView.PREVENT_TOUCH_ID, ted.mAction, nativeHandleTouchEvent(ted.mAction, ted.mX, - ted.mY, ted.mEventTime)).sendToTarget(); + ted.mY, ted.mEventTime, ted.mMetaState)).sendToTarget(); break; } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index c428dc0..2feed03 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -16,14 +16,17 @@ package android.widget; +import com.android.internal.R; +import com.google.android.collect.Lists; + import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.PixelFormat; import android.graphics.Paint; -import android.graphics.drawable.Drawable; +import android.graphics.PixelFormat; +import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; @@ -31,16 +34,13 @@ import android.util.SparseBooleanArray; import android.view.FocusFinder; import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.SoundEffectConstants; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.ViewParent; -import android.view.SoundEffectConstants; import android.view.accessibility.AccessibilityEvent; -import com.google.android.collect.Lists; -import com.android.internal.R; - import java.util.ArrayList; /* @@ -2722,7 +2722,8 @@ public class ListView extends AbsListView { /** * Determine the distance to the nearest edge of a view in a particular - * direciton. + * direction. + * * @param descendant A descendant of this list. * @return The distance, or 0 if the nearest edge is already on screen. */ @@ -3091,9 +3092,9 @@ public class ListView extends AbsListView { previouslyFocusedRect.offset(mScrollX, mScrollY); final ListAdapter adapter = mAdapter; - final int firstPosition = mFirstPosition; - // Don't cache the result of getChildCount here, it could change in layoutChildren. - if (adapter.getCount() < getChildCount() + firstPosition) { + // Don't cache the result of getChildCount or mFirstPosition here, + // it could change in layoutChildren. + if (adapter.getCount() < getChildCount() + mFirstPosition) { mLayoutMode = LAYOUT_NORMAL; layoutChildren(); } @@ -3103,6 +3104,7 @@ public class ListView extends AbsListView { Rect otherRect = mTempRect; int minDistance = Integer.MAX_VALUE; final int childCount = getChildCount(); + final int firstPosition = mFirstPosition; for (int i = 0; i < childCount; i++) { // only consider selectable views @@ -3307,9 +3309,9 @@ public class ListView extends AbsListView { * Sets the checked state of the specified position. The is only valid if * the choice mode has been set to {@link #CHOICE_MODE_SINGLE} or * {@link #CHOICE_MODE_MULTIPLE}. - * + * * @param position The item whose checked state is to be checked - * @param value The new checked sate for the item + * @param value The new checked state for the item */ public void setItemChecked(int position, boolean value) { if (mChoiceMode == CHOICE_MODE_NONE) { @@ -3392,10 +3394,11 @@ public class ListView extends AbsListView { } /** - * Returns the set of checked items ids. The result is only valid if - * the choice mode has not been set to {@link #CHOICE_MODE_SINGLE}. - * - * @return A new array which contains the id of each checked item in the list. + * Returns the set of checked items ids. The result is only valid if the + * choice mode has not been set to {@link #CHOICE_MODE_SINGLE}. + * + * @return A new array which contains the id of each checked item in the + * list. */ public long[] getCheckItemIds() { if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null && mAdapter != null) { @@ -3404,11 +3407,23 @@ public class ListView extends AbsListView { final long[] ids = new long[count]; final ListAdapter adapter = mAdapter; + int checkedCount = 0; for (int i = 0; i < count; i++) { - ids[i]= adapter.getItemId(states.keyAt(i)); + if (states.valueAt(i)) { + ids[checkedCount++] = adapter.getItemId(states.keyAt(i)); + } } - return ids; + // Trim array if needed. mCheckStates may contain false values + // resulting in checkedCount being smaller than count. + if (checkedCount == count) { + return ids; + } else { + final long[] result = new long[checkedCount]; + System.arraycopy(ids, 0, result, 0, checkedCount); + + return result; + } } return new long[0]; diff --git a/core/java/com/android/internal/app/DisableCarModeActivity.java b/core/java/com/android/internal/app/DisableCarModeActivity.java new file mode 100644 index 0000000..95dc1f9 --- /dev/null +++ b/core/java/com/android/internal/app/DisableCarModeActivity.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.app; + +import android.app.Activity; +import android.app.IUiModeManager; +import android.os.Bundle; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; + +public class DisableCarModeActivity extends Activity { + private static final String TAG = "DisableCarModeActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + IUiModeManager uiModeManager = IUiModeManager.Stub.asInterface( + ServiceManager.getService("uimode")); + uiModeManager.disableCarMode(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to disable car mode", e); + } + finish(); + } + +} diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index c5b869b..bc7dbf4 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -93,7 +93,7 @@ public class PackageHelper { public static boolean unMountSdDir(String cid) { try { - int rc = getMountService().unmountSecureContainer(cid); + int rc = getMountService().unmountSecureContainer(cid, false); if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc); return false; @@ -148,7 +148,7 @@ public class PackageHelper { public static boolean destroySdDir(String cid) { try { - int rc = getMountService().destroySecureContainer(cid); + int rc = getMountService().destroySecureContainer(cid, false); if (rc != StorageResultCode.OperationSucceeded) { Log.i(TAG, "Failed to destroy container " + cid); return false; diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index 15dcbd6..22c6e79 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -1,5 +1,6 @@ package com.android.internal.view; +import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; @@ -17,7 +18,7 @@ public class BaseIWindow extends IWindow.Stub { } public void resized(int w, int h, Rect coveredInsets, - Rect visibleInsets, boolean reportDraw) { + Rect visibleInsets, boolean reportDraw, Configuration newConfig) { if (reportDraw) { try { mSession.finishDrawing(this); |