Merge "Remove http/wml from the DumpRenderTree skipped list, as this directory no longer exists."
diff --git a/api/current.xml b/api/current.xml
index ed3f696..d792a41 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -5971,6 +5971,28 @@
visibility="public"
>
</field>
+<field name="overscrollFooter"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843456"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="overscrollHeader"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843455"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="overscrollMode"
type="int"
transient="false"
@@ -44348,7 +44370,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="filter" type="android.content.IntentFilter">
@@ -174601,6 +174623,19 @@
visibility="public"
>
</method>
+<method name="getXVelocity"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="id" type="int">
+</parameter>
+</method>
<method name="getYVelocity"
return="float"
abstract="false"
@@ -174612,6 +174647,19 @@
visibility="public"
>
</method>
+<method name="getYVelocity"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="id" type="int">
+</parameter>
+</method>
<method name="obtain"
return="android.view.VelocityTracker"
abstract="false"
@@ -179390,6 +179438,17 @@
visibility="public"
>
</method>
+<method name="getScaledPagingTouchSlop"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getScaledScrollBarSize"
return="int"
abstract="false"
@@ -204520,6 +204579,28 @@
visibility="public"
>
</method>
+<method name="getOverscrollFooter"
+ return="android.graphics.drawable.Drawable"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getOverscrollHeader"
+ return="android.graphics.drawable.Drawable"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="isItemChecked"
return="boolean"
abstract="false"
@@ -204665,6 +204746,32 @@
<parameter name="itemsCanFocus" type="boolean">
</parameter>
</method>
+<method name="setOverscrollFooter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="footer" type="android.graphics.drawable.Drawable">
+</parameter>
+</method>
+<method name="setOverscrollHeader"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="header" type="android.graphics.drawable.Drawable">
+</parameter>
+</method>
<method name="setSelection"
return="void"
abstract="false"
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index c8d1397..654ee68 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -404,6 +404,15 @@
}
}
+ /* count the source apk as code -- but only if it's not
+ * installed on the sdcard
+ */
+ if (strncmp(apkpath, SDCARD_DIR_PREFIX, 7) != 0) {
+ if (stat(apkpath, &s) == 0) {
+ codesize += stat_size(&s);
+ }
+ }
+
/* count the cached dexfile as code */
if (!create_cache_path(path, apkpath)) {
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 942a303..5e2c61e 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -232,7 +232,7 @@
fprintf(stderr, " -m max-number-of-frames-to-decode in each pass\n");
fprintf(stderr, " -b bug to reproduce\n");
fprintf(stderr, " -p(rofiles) dump decoder profiles supported\n");
- fprintf(stderr, " -t(humbnail) extract video thumbnail\n");
+ fprintf(stderr, " -t(humbnail) extract video thumbnail or album art\n");
fprintf(stderr, " -s(oftware) prefer software codec\n");
}
@@ -334,12 +334,24 @@
const char *filename = argv[k];
CHECK_EQ(retriever->setDataSource(filename), OK);
- CHECK_EQ(retriever->setMode(METADATA_MODE_FRAME_CAPTURE_ONLY), OK);
+ CHECK_EQ(retriever->setMode(
+ METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL),
+ OK);
sp<IMemory> mem = retriever->captureFrame();
- printf("captureFrame(%s) => %s\n",
- filename, mem != NULL ? "OK" : "FAILED");
+ if (mem != NULL) {
+ printf("captureFrame(%s) => OK\n", filename);
+ } else {
+ mem = retriever->extractAlbumArt();
+
+ if (mem != NULL) {
+ printf("extractAlbumArt(%s) => OK\n", filename);
+ } else {
+ printf("both captureFrame and extractAlbumArt "
+ "failed on file '%s'.\n", filename);
+ }
+ }
}
return 0;
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 2aaf5b0..6d0a266 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1071,8 +1071,20 @@
return;
}
+ final IAccountAuthenticator accountAuthenticator = mAuthenticator;
+ if (accountAuthenticator == null) {
+ // It is possible that the authenticator has died, which is indicated by
+ // mAuthenticator being set to null. If this happens then just abort.
+ // There is no need to send back a result or error in this case since
+ // that already happened when mAuthenticator was cleared.
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "checkAccount: aborting session since we are no longer"
+ + " connected to the authenticator, " + toDebugString());
+ }
+ return;
+ }
try {
- mAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures);
+ accountAuthenticator.hasFeatures(this, mAccountsOfType[mCurrentAccount], mFeatures);
} catch (RemoteException e) {
onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, "remote exception");
}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 3e426f5..bf9b021 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -668,7 +668,10 @@
// The user changed the query, remember it.
mUserQuery = s == null ? "" : s.toString();
}
- updateVoiceButton(mSearchAutoComplete.isEmpty());
+ // Always want to show the microphone if the context is voice.
+ updateVoiceButton(mSearchAutoComplete.isEmpty()
+ || (mAppSearchData != null && mAppSearchData.getBoolean(
+ SearchManager.CONTEXT_IS_VOICE)));
}
public void afterTextChanged(Editable s) {
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 0ed572a..625b120 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1544,6 +1544,15 @@
public final static String INTENT_ACTION_NONE = "android.search.action.ZILCH";
/**
+ * This means that context is voice, and therefore the SearchDialog should
+ * continue showing the microphone until the user indicates that he/she does
+ * not want to re-speak (e.g. by typing).
+ *
+ * @hide
+ */
+ public final static String CONTEXT_IS_VOICE = "android.search.CONTEXT_IS_VOICE";
+
+ /**
* Reference to the shared system search service.
*/
private static ISearchManager mService;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index bcef75e..d3cc4df 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -689,7 +689,7 @@
* @param uri The URI to modify.
* @param values The new field values. The key is the column name for the field.
A null value will remove an existing field value.
- * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause
+ * @param where A filter to apply to rows before updating, formatted as an SQL WHERE clause
(excluding the WHERE itself).
* @return The number of rows updated.
* @throws NullPointerException if uri or values are null
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 211a2ae..85769a6 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -124,6 +124,8 @@
*/
private static final long ERROR_NOTIFICATION_DELAY_MS = 1000 * 60 * 10; // 10 minutes
+ private static final int INITIALIZATION_UNBIND_DELAY_MS = 5000;
+
private static final String SYNC_WAKE_LOCK = "SyncManagerSyncWakeLock";
private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarmWakeLock";
@@ -283,6 +285,7 @@
private static final String ACTION_SYNC_ALARM = "android.content.syncmanager.SYNC_ALARM";
private final SyncHandler mSyncHandler;
+ private final Handler mMainHandler;
private volatile boolean mBootCompleted = false;
@@ -309,6 +312,7 @@
Process.THREAD_PRIORITY_BACKGROUND);
syncThread.start();
mSyncHandler = new SyncHandler(syncThread.getLooper());
+ mMainHandler = new Handler(mContext.getMainLooper());
mSyncAdapters = new SyncAdaptersCache(mContext);
mSyncAdapters.setListener(new RegisteredServicesCacheListener<SyncAdapterType>() {
@@ -423,32 +427,56 @@
Intent intent = new Intent();
intent.setAction("android.content.SyncAdapter");
intent.setComponent(syncAdapterInfo.componentName);
- mContext.bindService(intent, new InitializerServiceConnection(account, authority),
+ mContext.bindService(intent, new InitializerServiceConnection(account, authority, mContext,
+ mMainHandler),
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
}
- private class InitializerServiceConnection implements ServiceConnection {
+ private static class InitializerServiceConnection implements ServiceConnection {
private final Account mAccount;
private final String mAuthority;
+ private final Handler mHandler;
+ private volatile Context mContext;
+ private volatile boolean mInitialized;
- public InitializerServiceConnection(Account account, String authority) {
+ public InitializerServiceConnection(Account account, String authority, Context context,
+ Handler handler) {
mAccount = account;
mAuthority = authority;
+ mContext = context;
+ mHandler = handler;
+ mInitialized = false;
}
public void onServiceConnected(ComponentName name, IBinder service) {
try {
- ISyncAdapter.Stub.asInterface(service).initialize(mAccount, mAuthority);
+ if (!mInitialized) {
+ mInitialized = true;
+ ISyncAdapter.Stub.asInterface(service).initialize(mAccount, mAuthority);
+ }
} catch (RemoteException e) {
// doesn't matter, we will retry again later
} finally {
- mContext.unbindService(this);
+ // give the sync adapter time to initialize before unbinding from it
+ // TODO: change this API to not rely on this timing, http://b/2500805
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ if (mContext != null) {
+ mContext.unbindService(InitializerServiceConnection.this);
+ mContext = null;
+ }
+ }
+ }, INITIALIZATION_UNBIND_DELAY_MS);
}
}
public void onServiceDisconnected(ComponentName name) {
- mContext.unbindService(this);
+ if (mContext != null) {
+ mContext.unbindService(InitializerServiceConnection.this);
+ mContext = null;
+ }
}
+
}
/**
@@ -841,6 +869,7 @@
ISyncAdapter mSyncAdapter;
final long mStartTime;
long mTimeoutStartTime;
+ boolean mBound;
public ActiveSyncContext(SyncOperation syncOperation,
long historyRowId) {
@@ -895,15 +924,23 @@
com.android.internal.R.string.sync_binding_label);
intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
mContext, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0));
- return mContext.bindService(intent, this,
+ mBound = true;
+ final boolean bindResult = mContext.bindService(intent, this,
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
+ if (!bindResult) {
+ mBound = false;
+ }
+ return bindResult;
}
- void unBindFromSyncAdapter() {
+ protected void close() {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.d(TAG, "unBindFromSyncAdapter: connection " + this);
}
- mContext.unbindService(this);
+ if (mBound) {
+ mBound = false;
+ mContext.unbindService(this);
+ }
}
@Override
@@ -1580,6 +1617,7 @@
mSyncStorageEngine.setActiveSync(mActiveSyncContext);
if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo)) {
Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo);
+ mActiveSyncContext.close();
mActiveSyncContext = null;
mSyncStorageEngine.setActiveSync(mActiveSyncContext);
runStateIdle();
@@ -1669,13 +1707,13 @@
syncOperation.account, syncOperation.extras);
} catch (RemoteException remoteExc) {
Log.d(TAG, "runStateIdle: caught a RemoteException, rescheduling", remoteExc);
- mActiveSyncContext.unBindFromSyncAdapter();
+ mActiveSyncContext.close();
mActiveSyncContext = null;
mSyncStorageEngine.setActiveSync(mActiveSyncContext);
increaseBackoffSetting(syncOperation);
scheduleSyncOperation(new SyncOperation(syncOperation));
} catch (RuntimeException exc) {
- mActiveSyncContext.unBindFromSyncAdapter();
+ mActiveSyncContext.close();
mActiveSyncContext = null;
mSyncStorageEngine.setActiveSync(mActiveSyncContext);
Log.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
@@ -1741,7 +1779,7 @@
stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
upstreamActivity, downstreamActivity, elapsedTime);
- activeSyncContext.unBindFromSyncAdapter();
+ activeSyncContext.close();
if (syncResult != null && syncResult.tooManyDeletions) {
installHandleTooManyDeletesNotification(syncOperation.account,
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 8773f59..423f4bc 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -237,7 +237,7 @@
*
* {@hide}
*/
- public static final int FLAG_ON_SDCARD = 1<<20;
+ public static final int FLAG_EXTERNAL_STORAGE = 1<<20;
/**
* Value for {@link #flags}: Set to true if the application is
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index efd7bbc..271f477 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1896,6 +1896,10 @@
public abstract List<PackageInfo> getPreferredPackages(int flags);
/**
+ * @deprecated This is a protected API that should not have been available
+ * to third party applications. It is the platform's responsibility for
+ * assigning preferred activities and this can not be directly modified.
+ *
* Add a new preferred activity mapping to the system. This will be used
* to automatically select the given activity component when
* {@link Context#startActivity(Intent) Context.startActivity()} finds
@@ -1910,10 +1914,15 @@
* @param activity The component name of the activity that is to be
* preferred.
*/
+ @Deprecated
public abstract void addPreferredActivity(IntentFilter filter, int match,
ComponentName[] set, ComponentName activity);
/**
+ * @deprecated This is a protected API that should not have been available
+ * to third party applications. It is the platform's responsibility for
+ * assigning preferred activities and this can not be directly modified.
+ *
* Replaces an existing preferred activity mapping to the system, and if that were not present
* adds a new preferred activity. This will be used
* to automatically select the given activity component when
@@ -1930,6 +1939,7 @@
* preferred.
* @hide
*/
+ @Deprecated
public abstract void replacePreferredActivity(IntentFilter filter, int match,
ComponentName[] set, ComponentName activity);
@@ -1937,6 +1947,7 @@
* Remove all preferred activity mappings, previously added with
* {@link #addPreferredActivity}, from the
* system whose activities are implemented in the given package name.
+ * An application can only clear its own package(s).
*
* @param packageName The name of the package whose preferred activity
* mappings are to be removed.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 663d9e6..9736b01 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1503,7 +1503,7 @@
}
if ((flags & PARSE_ON_SDCARD) != 0) {
- ai.flags |= ApplicationInfo.FLAG_ON_SDCARD;
+ ai.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
}
if (sa.getBoolean(
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index b59e279..17b0330 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -346,7 +346,7 @@
ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
intent.putExtra(Phone.STATE_KEY, Phone.DataState.CONNECTED.toString());
intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, Phone.REASON_APN_CHANGED);
- intent.putExtra(Phone.DATA_APN_TYPES_KEY, mApnType);
+ intent.putExtra(Phone.DATA_APN_TYPES_KEY, mApnTypeToWatchFor);
intent.putExtra(Phone.DATA_APN_KEY, mApnName);
intent.putExtra(Phone.DATA_IFACE_NAME_KEY, mInterfaceName);
intent.putExtra(Phone.NETWORK_UNAVAILABLE_KEY, false);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fdde591..4995cac 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -29,6 +29,7 @@
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
@@ -989,6 +990,11 @@
return Settings.System.putFloat(cr, FONT_SCALE, config.fontScale);
}
+ /** @hide */
+ public static boolean hasInterestingConfigurationChanges(int changes) {
+ return (changes&ActivityInfo.CONFIG_FONT_SCALE) != 0;
+ }
+
public static boolean getShowGTalkServiceStatus(ContentResolver cr) {
return getInt(cr, SHOW_GTALK_SERVICE_STATUS, 0) != 0;
}
@@ -1708,6 +1714,7 @@
VOLUME_ALARM + APPEND_FOR_LAST_AUDIBLE,
VOLUME_NOTIFICATION + APPEND_FOR_LAST_AUDIBLE,
VOLUME_BLUETOOTH_SCO + APPEND_FOR_LAST_AUDIBLE,
+ VIBRATE_IN_SILENT,
TEXT_AUTO_REPLACE,
TEXT_AUTO_CAPS,
TEXT_AUTO_PUNCTUATE,
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 600ec7e..f02ad2a 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -233,25 +233,25 @@
}
}
- if (!easy) {
- // Ensure that none of the underlying characters are treated
- // as viable breakpoints, and that the entire run gets the
- // same bidi direction.
+ // Ensure that none of the underlying characters are treated
+ // as viable breakpoints, and that the entire run gets the
+ // same bidi direction.
- if (source instanceof Spanned) {
- Spanned sp = (Spanned) source;
- ReplacementSpan[] spans = sp.getSpans(start, end, ReplacementSpan.class);
+ if (source instanceof Spanned) {
+ Spanned sp = (Spanned) source;
+ ReplacementSpan[] spans = sp.getSpans(start, end, ReplacementSpan.class);
- for (int y = 0; y < spans.length; y++) {
- int a = sp.getSpanStart(spans[y]);
- int b = sp.getSpanEnd(spans[y]);
+ for (int y = 0; y < spans.length; y++) {
+ int a = sp.getSpanStart(spans[y]);
+ int b = sp.getSpanEnd(spans[y]);
- for (int x = a; x < b; x++) {
- chs[x - start] = '\uFFFC';
- }
+ for (int x = a; x < b; x++) {
+ chs[x - start] = '\uFFFC';
}
}
+ }
+ if (!easy) {
// XXX put override flags, etc. into chdirs
dir = bidi(dir, chs, chdirs, n, false);
diff --git a/core/java/android/text/util/Rfc822Tokenizer.java b/core/java/android/text/util/Rfc822Tokenizer.java
index 69d745d..952d833 100644
--- a/core/java/android/text/util/Rfc822Tokenizer.java
+++ b/core/java/android/text/util/Rfc822Tokenizer.java
@@ -74,7 +74,7 @@
name.setLength(0);
address.setLength(0);
- address.setLength(0);
+ comment.setLength(0);
} else if (c == '"') {
i++;
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index c17a724..aab76c4 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -259,8 +259,6 @@
*
* @param id Which pointer's velocity to return.
* @return The previously computed X velocity.
- *
- * @hide Pending API approval
*/
public float getXVelocity(int id) {
return mXVelocity[id];
@@ -272,8 +270,6 @@
*
* @param id Which pointer's velocity to return.
* @return The previously computed Y velocity.
- *
- * @hide Pending API approval
*/
public float getYVelocity(int id) {
return mYVelocity[id];
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 2344c42..2b78d2d 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -102,6 +102,12 @@
private static final int TOUCH_SLOP = 16;
/**
+ * Distance a touch can wander before we think the user is attempting a paged scroll
+ * (in dips)
+ */
+ private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 3;
+
+ /**
* Distance between the first touch and second touch to still be considered a double tap
*/
private static final int DOUBLE_TAP_SLOP = 100;
@@ -140,6 +146,7 @@
private final int mMaximumFlingVelocity;
private final int mScrollbarSize;
private final int mTouchSlop;
+ private final int mPagingTouchSlop;
private final int mDoubleTapSlop;
private final int mWindowTouchSlop;
private final int mMaximumDrawingCacheSize;
@@ -158,6 +165,7 @@
mMaximumFlingVelocity = MAXIMUM_FLING_VELOCITY;
mScrollbarSize = SCROLL_BAR_SIZE;
mTouchSlop = TOUCH_SLOP;
+ mPagingTouchSlop = PAGING_TOUCH_SLOP;
mDoubleTapSlop = DOUBLE_TAP_SLOP;
mWindowTouchSlop = WINDOW_TOUCH_SLOP;
//noinspection deprecation
@@ -184,6 +192,7 @@
mMaximumFlingVelocity = (int) (density * MAXIMUM_FLING_VELOCITY + 0.5f);
mScrollbarSize = (int) (density * SCROLL_BAR_SIZE + 0.5f);
mTouchSlop = (int) (density * TOUCH_SLOP + 0.5f);
+ mPagingTouchSlop = (int) (density * PAGING_TOUCH_SLOP + 0.5f);
mDoubleTapSlop = (int) (density * DOUBLE_TAP_SLOP + 0.5f);
mWindowTouchSlop = (int) (density * WINDOW_TOUCH_SLOP + 0.5f);
@@ -339,6 +348,14 @@
public int getScaledTouchSlop() {
return mTouchSlop;
}
+
+ /**
+ * @return Distance a touch can wander before we think the user is scrolling a full page
+ * in dips
+ */
+ public int getScaledPagingTouchSlop() {
+ return mPagingTouchSlop;
+ }
/**
* @return Distance between the first touch and second touch to still be
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index ab3260e..b39cb9d 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -627,8 +627,9 @@
* returned, all windows given to layoutWindow() <em>must</em> have had a
* frame assigned.
*
- * @return Return any bit set of {@link #FINISH_LAYOUT_REDO_LAYOUT}
- * and {@link #FINISH_LAYOUT_REDO_CONFIG}.
+ * @return Return any bit set of {@link #FINISH_LAYOUT_REDO_LAYOUT},
+ * {@link #FINISH_LAYOUT_REDO_CONFIG}, {@link #FINISH_LAYOUT_REDO_WALLPAPER},
+ * or {@link #FINISH_LAYOUT_REDO_ANIM}.
*/
public int finishLayoutLw();
@@ -638,6 +639,8 @@
static final int FINISH_LAYOUT_REDO_CONFIG = 0x0002;
/** Wallpaper may need to move */
static final int FINISH_LAYOUT_REDO_WALLPAPER = 0x0004;
+ /** Need to recompute animations */
+ static final int FINISH_LAYOUT_REDO_ANIM = 0x0008;
/**
* Called when animation of the windows is about to start.
@@ -661,10 +664,11 @@
* something that may have modified the animation state of another window,
* be sure to return true in order to perform another animation frame.
*
- * @return Return true if animation state may have changed (so that another
- * frame of animation will be run).
+ * @return Return any bit set of {@link #FINISH_LAYOUT_REDO_LAYOUT},
+ * {@link #FINISH_LAYOUT_REDO_CONFIG}, {@link #FINISH_LAYOUT_REDO_WALLPAPER},
+ * or {@link #FINISH_LAYOUT_REDO_ANIM}.
*/
- public boolean finishAnimationLw();
+ public int finishAnimationLw();
/**
* Return true if it is okay to perform animations for an app transition
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6f6ee1d..6f2d070 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2199,14 +2199,15 @@
// Sets r to be our visible rectangle in content coordinates
private void calcOurContentVisibleRect(Rect r) {
calcOurVisibleRect(r);
- r.left = viewToContentX(r.left);
+ // since we might overscroll, pin the rect to the bounds of the content
+ r.left = Math.max(viewToContentX(r.left), 0);
// viewToContentY will remove the total height of the title bar. Add
// the visible height back in to account for the fact that if the title
// bar is partially visible, the part of the visible rect which is
// displaying our content is displaced by that amount.
- r.top = viewToContentY(r.top + getVisibleTitleHeight());
- r.right = viewToContentX(r.right);
- r.bottom = viewToContentY(r.bottom);
+ r.top = Math.max(viewToContentY(r.top + getVisibleTitleHeight()), 0);
+ r.right = Math.min(viewToContentX(r.right), mContentWidth);
+ r.bottom = Math.min(viewToContentY(r.bottom), mContentHeight);
}
static class ViewSizeData {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index d4552e3..0594844 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -117,6 +117,9 @@
Drawable mDivider;
int mDividerHeight;
+
+ Drawable mOverscrollHeader;
+ Drawable mOverscrollFooter;
private boolean mIsCacheColorOpaque;
private boolean mDividerIsOpaque;
@@ -171,6 +174,16 @@
// If a divider is specified use its intrinsic height for divider height
setDivider(d);
}
+
+ final Drawable osHeader = a.getDrawable(com.android.internal.R.styleable.ListView_overscrollHeader);
+ if (osHeader != null) {
+ setOverscrollHeader(osHeader);
+ }
+
+ final Drawable osFooter = a.getDrawable(com.android.internal.R.styleable.ListView_overscrollFooter);
+ if (osFooter != null) {
+ setOverscrollFooter(osFooter);
+ }
// Use the height specified, zero being the default
final int dividerHeight = a.getDimensionPixelSize(
@@ -2934,12 +2947,51 @@
super.setCacheColorHint(color);
}
+ void drawOverscrollHeader(Canvas canvas, Drawable drawable, Rect bounds) {
+ final int height = drawable.getMinimumHeight();
+
+ canvas.save();
+ canvas.clipRect(bounds);
+
+ final int span = bounds.bottom - bounds.top;
+ if (span < height) {
+ bounds.top = bounds.bottom - height;
+ }
+
+ drawable.setBounds(bounds);
+ drawable.draw(canvas);
+
+ canvas.restore();
+ }
+
+ void drawOverscrollFooter(Canvas canvas, Drawable drawable, Rect bounds) {
+ final int height = drawable.getMinimumHeight();
+
+ canvas.save();
+ canvas.clipRect(bounds);
+
+ final int span = bounds.bottom - bounds.top;
+ if (span < height) {
+ bounds.bottom = bounds.top + height;
+ }
+
+ drawable.setBounds(bounds);
+ drawable.draw(canvas);
+
+ canvas.restore();
+ }
+
@Override
protected void dispatchDraw(Canvas canvas) {
// Draw the dividers
final int dividerHeight = mDividerHeight;
+ final Drawable overscrollHeader = mOverscrollHeader;
+ final Drawable overscrollFooter = mOverscrollFooter;
+ final boolean drawOverscrollHeader = overscrollHeader != null;
+ final boolean drawOverscrollFooter = overscrollFooter != null;
+ final boolean drawDividers = dividerHeight > 0 && mDivider != null;
- if (dividerHeight > 0 && mDivider != null) {
+ if (drawDividers || drawOverscrollHeader || drawOverscrollFooter) {
// Only modify the top and bottom in the loop, we set the left and right here
final Rect bounds = mTempRect;
bounds.left = mPaddingLeft;
@@ -2947,7 +2999,8 @@
final int count = getChildCount();
final int headerCount = mHeaderViewInfos.size();
- final int footerLimit = mItemCount - mFooterViewInfos.size() - 1;
+ final int itemCount = mItemCount;
+ final int footerLimit = itemCount - mFooterViewInfos.size() - 1;
final boolean headerDividers = mHeaderDividersEnabled;
final boolean footerDividers = mFooterDividersEnabled;
final int first = mFirstPosition;
@@ -2957,7 +3010,7 @@
// fill a rect where the dividers would be for non-selectable items
// If the list is opaque and the background is also opaque, we don't
// need to draw anything since the background will do it for us
- final boolean fillForMissingDividers = isOpaque() && !super.isOpaque();
+ final boolean fillForMissingDividers = drawDividers && isOpaque() && !super.isOpaque();
if (fillForMissingDividers && mDividerPaint == null && mIsCacheColorOpaque) {
mDividerPaint = new Paint();
@@ -2965,15 +3018,22 @@
}
final Paint paint = mDividerPaint;
+ final int listBottom = mBottom - mTop - mListPadding.bottom + mScrollY;
if (!mStackFromBottom) {
- int bottom;
- int listBottom = mBottom - mTop - mListPadding.bottom + mScrollY;
+ int bottom = 0;
- // Draw top divider for overscroll
- if (count > 0 && mScrollY < 0) {
- bounds.bottom = 0;
- bounds.top = -dividerHeight;
- drawDivider(canvas, bounds, -1);
+ // Draw top divider or header for overscroll
+ final int scrollY = mScrollY;
+ if (count > 0 && scrollY < 0) {
+ if (drawOverscrollHeader) {
+ bounds.bottom = 0;
+ bounds.top = scrollY;
+ drawOverscrollHeader(canvas, overscrollHeader, bounds);
+ } else if (drawDividers) {
+ bounds.bottom = 0;
+ bounds.top = -dividerHeight;
+ drawDivider(canvas, bounds, -1);
+ }
}
for (int i = 0; i < count; i++) {
@@ -2982,7 +3042,8 @@
View child = getChildAt(i);
bottom = child.getBottom();
// Don't draw dividers next to items that are not enabled
- if (bottom < listBottom) {
+ if (drawDividers &&
+ (bottom < listBottom && !(drawOverscrollFooter && i == count - 1))) {
if ((areAllItemsSelectable ||
(adapter.isEnabled(first + i) && (i == count - 1 ||
adapter.isEnabled(first + i + 1))))) {
@@ -2997,17 +3058,34 @@
}
}
}
+
+ final int overFooterBottom = mBottom + mScrollY;
+ if (drawOverscrollFooter && first + count == itemCount &&
+ overFooterBottom > bottom) {
+ bounds.top = bottom;
+ bounds.bottom = overFooterBottom;
+ drawOverscrollFooter(canvas, overscrollFooter, bounds);
+ }
} else {
int top;
int listTop = mListPadding.top;
- for (int i = 0; i < count; i++) {
+ final int scrollY = mScrollY;
+
+ if (count > 0 && drawOverscrollHeader) {
+ bounds.top = scrollY;
+ bounds.bottom = getChildAt(0).getTop();
+ drawOverscrollHeader(canvas, overscrollHeader, bounds);
+ }
+
+ final int start = drawOverscrollHeader ? 1 : 0;
+ for (int i = start; i < count; i++) {
if ((headerDividers || first + i >= headerCount) &&
(footerDividers || first + i < footerLimit)) {
View child = getChildAt(i);
top = child.getTop();
// Don't draw dividers next to items that are not enabled
- if (top > listTop) {
+ if (drawDividers && top > listTop) {
if ((areAllItemsSelectable ||
(adapter.isEnabled(first + i) && (i == count - 1 ||
adapter.isEnabled(first + i + 1))))) {
@@ -3026,6 +3104,19 @@
}
}
}
+
+ if (count > 0 && scrollY > 0) {
+ if (drawOverscrollFooter) {
+ final int absListBottom = mBottom;
+ bounds.top = absListBottom;
+ bounds.bottom = absListBottom + scrollY;
+ drawOverscrollFooter(canvas, overscrollFooter, bounds);
+ } else if (drawDividers) {
+ bounds.top = listBottom;
+ bounds.bottom = listBottom + dividerHeight;
+ drawDivider(canvas, bounds, -1);
+ }
+ }
}
}
@@ -3132,6 +3223,45 @@
mFooterDividersEnabled = footerDividersEnabled;
invalidate();
}
+
+ /**
+ * Sets the drawable that will be drawn above all other list content.
+ * This area can become visible when the user overscrolls the list.
+ *
+ * @param header The drawable to use
+ */
+ public void setOverscrollHeader(Drawable header) {
+ mOverscrollHeader = header;
+ if (mScrollY < 0) {
+ invalidate();
+ }
+ }
+
+ /**
+ * @return The drawable that will be drawn above all other list content
+ */
+ public Drawable getOverscrollHeader() {
+ return mOverscrollHeader;
+ }
+
+ /**
+ * Sets the drawable that will be drawn below all other list content.
+ * This area can become visible when the user overscrolls the list,
+ * or when the list's content does not fully fill the container area.
+ *
+ * @param footer The drawable to use
+ */
+ public void setOverscrollFooter(Drawable footer) {
+ mOverscrollFooter = footer;
+ invalidate();
+ }
+
+ /**
+ * @return The drawable that will be drawn below all other list content
+ */
+ public Drawable getOverscrollFooter() {
+ return mOverscrollFooter;
+ }
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 7b21be5..64c9c99 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6989,6 +6989,10 @@
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ if (!isShown()) {
+ return false;
+ }
+
final boolean isPassword = isPasswordInputType(mInputType);
if (!isPassword) {
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index de6a175..80efca4 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -40,6 +40,10 @@
public static final int RECOMMEND_FAILED_ALREADY_EXISTS = -4;
private static final boolean localLOGV = true;
private static final String TAG = "PackageHelper";
+ // App installation location settings values
+ public static final int APP_INSTALL_AUTO = 0;
+ public static final int APP_INSTALL_INTERNAL = 1;
+ public static final int APP_INSTALL_EXTERNAL = 2;
public static IMountService getMountService() {
IBinder service = ServiceManager.getService("mount");
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 9965fe5..b6f3997 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -331,12 +331,14 @@
// i.e. dynamically allocated, since its lifetime may exceed the current stack
// frame.
static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding,
- jobject options, bool allowPurgeable) {
+ jobject options, bool allowPurgeable,
+ bool forcePurgeable = false) {
int sampleSize = 1;
SkImageDecoder::Mode mode = SkImageDecoder::kDecodePixels_Mode;
SkBitmap::Config prefConfig = SkBitmap::kNo_Config;
bool doDither = true;
- bool isPurgeable = allowPurgeable && optionsPurgeable(env, options);
+ bool isPurgeable = forcePurgeable ||
+ (allowPurgeable && optionsPurgeable(env, options));
bool reportSizeToVM = optionsReportSizeToVM(env, options);
if (NULL != options) {
@@ -568,8 +570,10 @@
jobject options) { // BitmapFactory$Options
SkStream* stream;
Asset* asset = reinterpret_cast<Asset*>(native_asset);
+ // assets can always be rebuilt, so force this
+ bool forcePurgeable = true;
- if (optionsPurgeable(env, options)) {
+ if (forcePurgeable || optionsPurgeable(env, options)) {
// if we could "ref/reopen" the asset, we may not need to copy it here
// and we could assume optionsShareable, since assets are always RO
stream = copyAssetToStream(asset);
@@ -582,7 +586,7 @@
stream = new AssetStreamAdaptor(asset);
}
SkAutoUnref aur(stream);
- return doDecode(env, stream, padding, options, true);
+ return doDecode(env, stream, padding, options, true, forcePurgeable);
}
static jobject nativeDecodeByteArray(JNIEnv* env, jobject, jbyteArray byteArray,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f1e614b..4e2caa0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -648,7 +648,7 @@
for details. -->
<permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
- android:protectionLevel="dangerous"
+ android:protectionLevel="signature"
android:label="@string/permlab_setPreferredApplications"
android:description="@string/permdesc_setPreferredApplications" />
diff --git a/core/res/res/drawable-hdpi/stat_notify_car_mode.png b/core/res/res/drawable-hdpi/stat_notify_car_mode.png
index 6c51b32..03499a4 100644
--- a/core/res/res/drawable-hdpi/stat_notify_car_mode.png
+++ b/core/res/res/drawable-hdpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_car_mode.png b/core/res/res/drawable-mdpi/stat_notify_car_mode.png
index c664244..0272e6b 100644
--- a/core/res/res/drawable-mdpi/stat_notify_car_mode.png
+++ b/core/res/res/drawable-mdpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/layout/status_bar_expanded.xml b/core/res/res/layout/status_bar_expanded.xml
index 30138a7..d443247 100644
--- a/core/res/res/layout/status_bar_expanded.xml
+++ b/core/res/res/layout/status_bar_expanded.xml
@@ -86,6 +86,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="none"
+ android:overscrollMode="ifContentScrolls"
>
<com.android.server.status.NotificationLinearLayout
android:id="@+id/notificationLinearLayout"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 1ced121..f5e2f1d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1747,6 +1747,10 @@
<!-- When set to false, the ListView will not draw the divider before each footer view.
The default value is true. -->
<attr name="footerDividersEnabled" format="boolean" />
+ <!-- Drawable to draw above list content. -->
+ <attr name="overscrollHeader" format="reference" />
+ <!-- Drawable to draw below list content. -->
+ <attr name="overscrollFooter" format="reference" />
</declare-styleable>
<declare-styleable name="MenuView">
<!-- Default appearance of menu item text. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 36a8f5b..8c00884 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1235,6 +1235,8 @@
<public type="attr" name="stripLeft" id="0x010102bc" />
<public type="attr" name="stripRight" id="0x010102bd" />
<public type="attr" name="stripEnabled" id="0x010102be" />
+ <public type="attr" name="overscrollHeader" id="0x010102bf" />
+ <public type="attr" name="overscrollFooter" id="0x010102c0" />
<public type="anim" name="cycle_interpolator" id="0x010a000c" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 6bc6f2e..6a7c6ec 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -70,9 +70,6 @@
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.HARDWARE_TEST" />
- <uses-permission android:name="android.permission.ACCESSIBILITY_EVENT_VIEW_TYPES" />
- <uses-permission android:name="android.permission.ACCESSIBILITY_EVENT_TRANSITION_TYPES" />
- <uses-permission android:name="android.permission.ACCESSIBILITY_EVENT_NOTIFICATION_TYPES" />
<!-- package manager test permissions -->
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
@@ -1002,7 +999,7 @@
</intent-filter>
</activity>
- <service android:name="android.accessibility.AccessibilityTestService">
+ <service android:name="android.accessibilityservice.AccessibilityTestService">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 1d3f82d..f05e84c 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -161,5 +161,9 @@
mRS.destroy();
mRS = null;
}
+
+ public void createRenderScript(RenderScriptGL rs) {
+ mRS = rs;
+ }
}
diff --git a/include/media/stagefright/StagefrightMediaScanner.h b/include/media/stagefright/StagefrightMediaScanner.h
index af125dc..4437eee 100644
--- a/include/media/stagefright/StagefrightMediaScanner.h
+++ b/include/media/stagefright/StagefrightMediaScanner.h
@@ -22,7 +22,7 @@
namespace android {
-struct StagefrightMetadataRetriever;
+struct MediaMetadataRetriever;
struct StagefrightMediaScanner : public MediaScanner {
StagefrightMediaScanner();
@@ -35,7 +35,7 @@
virtual char *extractAlbumArt(int fd);
private:
- sp<StagefrightMetadataRetriever> mRetriever;
+ sp<MediaMetadataRetriever> mRetriever;
StagefrightMediaScanner(const StagefrightMediaScanner &);
StagefrightMediaScanner &operator=(const StagefrightMediaScanner &);
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 6041b83..4614b53 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -22,6 +22,7 @@
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
/**
@@ -57,12 +58,12 @@
public byte[] get(byte[] key) {
ArrayList<byte[]> values = execute('g', key);
- return (values == null || values.size() == 0) ? null : values.get(0);
+ return (values == null || values.isEmpty()) ? null : values.get(0);
}
public String get(String key) {
- byte[] value = get(key.getBytes());
- return (value == null) ? null : new String(value);
+ byte[] value = get(getBytes(key));
+ return (value == null) ? null : toString(value);
}
public boolean put(byte[] key, byte[] value) {
@@ -71,7 +72,7 @@
}
public boolean put(String key, String value) {
- return put(key.getBytes(), value.getBytes());
+ return put(getBytes(key), getBytes(value));
}
public boolean delete(byte[] key) {
@@ -80,7 +81,7 @@
}
public boolean delete(String key) {
- return delete(key.getBytes());
+ return delete(getBytes(key));
}
public boolean contains(byte[] key) {
@@ -89,7 +90,7 @@
}
public boolean contains(String key) {
- return contains(key.getBytes());
+ return contains(getBytes(key));
}
public byte[][] saw(byte[] prefix) {
@@ -98,13 +99,13 @@
}
public String[] saw(String prefix) {
- byte[][] values = saw(prefix.getBytes());
+ byte[][] values = saw(getBytes(prefix));
if (values == null) {
return null;
}
String[] strings = new String[values.length];
for (int i = 0; i < values.length; ++i) {
- strings[i] = new String(values[i]);
+ strings[i] = toString(values[i]);
}
return strings;
}
@@ -120,7 +121,7 @@
}
public boolean password(String oldPassword, String newPassword) {
- return password(oldPassword.getBytes(), newPassword.getBytes());
+ return password(getBytes(oldPassword), getBytes(newPassword));
}
public boolean password(byte[] password) {
@@ -128,7 +129,7 @@
}
public boolean password(String password) {
- return password(password.getBytes());
+ return password(getBytes(password));
}
public boolean lock() {
@@ -142,7 +143,7 @@
}
public boolean unlock(String password) {
- return unlock(password.getBytes());
+ return unlock(getBytes(password));
}
public int getLastError() {
@@ -208,4 +209,22 @@
}
return null;
}
+
+ private static byte[] getBytes(String string) {
+ try {
+ return string.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // will never happen
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static String toString(byte[] bytes) {
+ try {
+ return new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // will never happen
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 569d8da..6630a4f 100755
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -39,6 +39,9 @@
private static final String TEST_KEYNAME2 = "testkey2";
private static final String TEST_KEYVALUE = "test value";
+ // "Hello, World" in Chinese
+ private static final String TEST_I18N = "\u4F60\u597D, \u4E16\u754C";
+
private KeyStore mKeyStore = null;
public KeyStoreTest() {
@@ -83,6 +86,14 @@
assertTrue(mKeyStore.put(TEST_KEYNAME, TEST_KEYVALUE));
}
+ public void testI18n() throws Exception {
+ assertFalse(mKeyStore.put(TEST_I18N, TEST_I18N));
+ assertFalse(mKeyStore.contains(TEST_I18N));
+ mKeyStore.password(TEST_I18N);
+ assertTrue(mKeyStore.put(TEST_I18N, TEST_I18N));
+ assertTrue(mKeyStore.contains(TEST_I18N));
+ }
+
public void testDelete() throws Exception {
assertTrue(mKeyStore.delete(TEST_KEYNAME));
mKeyStore.password(TEST_PASSWD);
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index d2cec0c..f623295b 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -104,7 +104,8 @@
{ // scope for the lock
Mutex::Autolock _l(mLock);
- if ( !( mCurrentState & ( MEDIA_PLAYER_IDLE | MEDIA_PLAYER_STATE_ERROR ) ) ) {
+ if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
+ (mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
LOGE("setDataSource called in state %d", mCurrentState);
return INVALID_OPERATION;
}
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index b1eca2b..34fb2bc 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -20,7 +20,8 @@
#include <media/stagefright/StagefrightMediaScanner.h>
-#include "include/StagefrightMetadataRetriever.h"
+#include <media/mediametadataretriever.h>
+#include <private/media/VideoFrame.h>
// Sonivox includes
#include <libsonivox/eas.h>
@@ -32,7 +33,7 @@
namespace android {
StagefrightMediaScanner::StagefrightMediaScanner()
- : mRetriever(new StagefrightMetadataRetriever) {
+ : mRetriever(new MediaMetadataRetriever) {
}
StagefrightMediaScanner::~StagefrightMediaScanner() {}
@@ -146,6 +147,8 @@
status_t StagefrightMediaScanner::processFile(
const char *path, const char *mimeType,
MediaScannerClient &client) {
+ LOGV("processFile '%s'.", path);
+
client.setLocale(locale());
client.beginFile();
@@ -218,6 +221,8 @@
}
char *StagefrightMediaScanner::extractAlbumArt(int fd) {
+ LOGV("extractAlbumArt %d", fd);
+
off_t size = lseek(fd, 0, SEEK_END);
if (size < 0) {
return NULL;
@@ -227,15 +232,14 @@
if (mRetriever->setDataSource(fd, 0, size) == OK
&& mRetriever->setMode(
METADATA_MODE_FRAME_CAPTURE_ONLY) == OK) {
- MediaAlbumArt *art = mRetriever->extractAlbumArt();
+ sp<IMemory> mem = mRetriever->extractAlbumArt();
- if (art != NULL) {
+ if (mem != NULL) {
+ MediaAlbumArt *art = static_cast<MediaAlbumArt *>(mem->pointer());
+
char *data = (char *)malloc(art->mSize + 4);
*(int32_t *)data = art->mSize;
- memcpy(&data[4], art->mData, art->mSize);
-
- delete art;
- art = NULL;
+ memcpy(&data[4], &art[1], art->mSize);
return data;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index 0e883e6..9a48c92 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -394,7 +394,7 @@
"ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
"Blues", "ID3V2.3 Title", "1234", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album",
- "ID3V2.3 Artist", null, null, null, "255", "ID3V2.3 Title", "1234", "295", "1", null},
+ "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", null, "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album",
@@ -416,7 +416,7 @@
null, null, "231180", "1", null},
{"/sdcard/media_api/metaDataTestMedias/M4A/Jaws Of Life_ver1.m4a", "1/8", "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
- "13", "Jaws Of Life", "2005", "449329", "1", "m4a composer"},
+ "12", "Jaws Of Life", "2005", "449329", "1", "m4a composer"},
{"/sdcard/media_api/metaDataTestMedias/M4V/sample_iPod.m4v", null, null,
null, null, null, "20051220T202015.000Z",
null, null, null, "85500", "2", null},
@@ -425,7 +425,7 @@
null, null, "2005", "231180", "1", null},
{"/sdcard/media_api/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", "2/0", "mp4 album Kung Fu Panda",
"mp4 artist Kung Fu Panda", null, null, "20080517T091451.000Z",
- "41", "Kung Fu Panda", "2008", "128521", "2", "mp4 composer"},
+ "40", "Kung Fu Panda", "2008", "128521", "2", "mp4 composer"},
{"/sdcard/media_api/metaDataTestMedias/OGG/Ring_Classic_02.ogg", null, "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
null, null, "2005", "231180", "1", null},
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 4635f48..7714911 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -349,11 +349,11 @@
int installPreference = Settings.System.getInt(getApplicationContext()
.getContentResolver(),
Settings.System.DEFAULT_INSTALL_LOCATION,
- PackageInfo.INSTALL_LOCATION_AUTO);
- if (installPreference == 1) {
+ PackageHelper.APP_INSTALL_AUTO);
+ if (installPreference == PackageHelper.APP_INSTALL_INTERNAL) {
installOnlyInternal = true;
auto = false;
- } else if (installPreference == 2) {
+ } else if (installPreference == PackageHelper.APP_INSTALL_EXTERNAL) {
installOnlyOnSd = true;
auto = false;
}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index bd131e0..34302c4 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -56,7 +56,10 @@
<bool name="def_mount_ums_autostart">false</bool>
<bool name="def_mount_ums_prompt">true</bool>
<bool name="def_mount_ums_notify_enabled">true</bool>
+ <!-- Enable User preference for setting install location -->
<bool name="set_install_location">true</bool>
+ <!-- Default install location if user preference for setting install location is turned on. -->
+ <integer name="def_install_location">2</integer>
<!-- user interface sound effects -->
<integer name="def_power_sounds_enabled">1</integer>
@@ -70,4 +73,6 @@
<string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
<string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
+ <!-- Default for Settings.System.VIBRATE_IN_SILENT -->
+ <bool name="def_vibrate_in_silent">true</bool>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index b05f1b3..ba66dc5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -61,7 +61,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 52;
+ private static final int DATABASE_VERSION = 54;
private Context mContext;
@@ -634,7 +634,45 @@
upgradeVersion = 52;
}
- if (upgradeVersion != currentVersion) {
+ if (upgradeVersion == 52) {
+ // new vibration/silent mode settings
+ db.beginTransaction();
+ try {
+ SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
+ R.bool.def_vibrate_in_silent);
+ stmt.close();
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+
+ upgradeVersion = 53;
+ }
+
+ if (upgradeVersion == 53) {
+ /*
+ * New settings for set install location UI.
+ */
+ db.beginTransaction();
+ try {
+ SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadIntegerSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
+ R.integer.def_install_location);
+ stmt.close();
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+
+ upgradeVersion = 54;
+ }
+
+ // *** Remember to update DATABASE_VERSION above!
+
+ if (upgradeVersion != currentVersion) {
Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
+ ", must wipe the settings provider");
db.execSQL("DROP TABLE IF EXISTS system");
@@ -924,12 +962,16 @@
loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
R.bool.def_notification_pulse);
- loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION, R.bool.set_install_location);
- loadSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
- PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION,
+ R.bool.set_install_location);
+ loadIntegerSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
+ R.integer.def_install_location);
loadUISoundEffectsSettings(stmt);
+ loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
+ R.bool.def_vibrate_in_silent);
+
stmt.close();
}
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 43fe6ab..1ffb427 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -821,6 +821,11 @@
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
} else {
+ if (Intent.ACTION_PACKAGE_REMOVED.equals(action)
+ && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ // This package is being updated; don't kill its alarms.
+ return;
+ }
Uri data = intent.getData();
if (data != null) {
String pkg = data.getSchemeSpecificPart();
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 70deb3e..fa06244 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -668,6 +668,7 @@
synchronized(this) {
// check if this process still has an outstanding start request
if (!mFeatureUsers.contains(u)) {
+ if (DBG) Slog.d(TAG, "ignoring - this process has no outstanding requests");
return 1;
}
u.unlinkDeathRecipient();
@@ -706,6 +707,7 @@
}
tracker = mNetTrackers[usedNetworkType];
if (tracker == null) {
+ if (DBG) Slog.d(TAG, "ignoring - no known tracker for net type " + usedNetworkType);
return -1;
}
if (usedNetworkType != networkType) {
@@ -720,7 +722,7 @@
callTeardown = true;
}
}
-
+ if (DBG) Slog.d(TAG, "Doing network teardown");
if (callTeardown) {
tracker.teardown();
return 1;
diff --git a/services/java/com/android/server/DropBoxManagerService.java b/services/java/com/android/server/DropBoxManagerService.java
index 667953c..b38f1d2 100644
--- a/services/java/com/android/server/DropBoxManagerService.java
+++ b/services/java/com/android/server/DropBoxManagerService.java
@@ -603,7 +603,9 @@
for (EntryFile late : future) {
mAllFiles.blocks -= late.blocks;
FileList tagFiles = mFilesByTag.get(late.tag);
- if (tagFiles.contents.remove(late)) tagFiles.blocks -= late.blocks;
+ if (tagFiles != null && tagFiles.contents.remove(late)) {
+ tagFiles.blocks -= late.blocks;
+ }
if ((late.flags & DropBoxManager.IS_EMPTY) == 0) {
enrollEntry(new EntryFile(
late.file, mDropBoxDir, late.tag, t++, late.flags, mBlockSize));
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 371fa37..63afabc 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4589,7 +4589,7 @@
} else {
// When replacing apps make sure we honour
// the existing app location if not overwritten by other options
- boolean prevOnSd = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0;
+ boolean prevOnSd = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
if (onSd) {
// Install flag overrides everything.
return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
@@ -5995,7 +5995,7 @@
// Delete application code and resources
if (deleteCodeAndResources) {
// TODO can pick up from PackageSettings as well
- int installFlags = ((p.applicationInfo.flags & ApplicationInfo.FLAG_ON_SDCARD)!=0) ?
+ int installFlags = ((p.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE)!=0) ?
PackageManager.INSTALL_EXTERNAL : 0;
installFlags |= ((p.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK)!=0) ?
PackageManager.INSTALL_FORWARD_LOCK : 0;
@@ -6321,10 +6321,14 @@
}
public void clearPackagePreferredActivities(String packageName) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
-
synchronized (mPackages) {
+ int uid = Binder.getCallingUid();
+ PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg.applicationInfo.uid != uid) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
+ }
+
if (clearPackagePreferredActivitiesLP(packageName)) {
mSettings.writeLP();
}
@@ -7214,7 +7218,7 @@
void setFlags(int pkgFlags) {
this.pkgFlags = (pkgFlags & ApplicationInfo.FLAG_SYSTEM) |
(pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) |
- (pkgFlags & ApplicationInfo.FLAG_ON_SDCARD) |
+ (pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) |
(pkgFlags & ApplicationInfo.FLAG_NEVER_ENCRYPT);
}
}
@@ -9058,7 +9062,7 @@
return false;
}
mMediaMounted = mediaStatus;
- Set<String> appList = mSettings.findPackagesWithFlag(ApplicationInfo.FLAG_ON_SDCARD);
+ Set<String> appList = mSettings.findPackagesWithFlag(ApplicationInfo.FLAG_EXTERNAL_STORAGE);
ret = appList != null && appList.size() > 0;
}
// Queue up an async operation since the package installation may take a little while.
@@ -9107,7 +9111,7 @@
if (DEBUG_SD_INSTALL) Log.i(TAG, "Looking for pkg : " + pkgName);
PackageSetting ps = mSettings.mPackages.get(pkgName);
if (ps != null && ps.codePathString != null &&
- (ps.pkgFlags & ApplicationInfo.FLAG_ON_SDCARD) != 0) {
+ (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
if (DEBUG_SD_INSTALL) Log.i(TAG, "Container : " + cid +
" corresponds to pkg : " + pkgName +
" at code path: " + ps.codePathString);
@@ -9333,7 +9337,7 @@
} else {
newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ?
PackageManager.INSTALL_EXTERNAL : 0;
- currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0 ?
+ currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ?
PackageManager.INSTALL_EXTERNAL : 0;
if (newFlags == currFlags) {
Log.w(TAG, "No move required. Trying to move to same location");
@@ -9400,9 +9404,9 @@
ps.resourcePathString = ps.resourcePath.getPath();
// Set the application info flag correctly.
if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
- pkg.applicationInfo.flags |= ApplicationInfo.FLAG_ON_SDCARD;
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
} else {
- pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_ON_SDCARD;
+ pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
}
ps.setFlags(pkg.applicationInfo.flags);
mAppDirs.remove(oldCodePath);
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 5f23a90..8103d7c 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -88,7 +88,9 @@
private boolean mComputedNightMode;
private int mCurUiMode = 0;
+ private int mSetUiMode = 0;
+ private boolean mHoldingConfiguration = false;
private Configuration mConfiguration = new Configuration();
private boolean mSystemReady;
@@ -114,25 +116,32 @@
return;
}
- // Launch a dock activity
- String category;
- if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
- // Only launch car home when car mode is enabled.
- category = Intent.CATEGORY_CAR_DOCK;
- } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) {
- category = Intent.CATEGORY_DESK_DOCK;
- } else {
- category = null;
- }
- if (category != null) {
- intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(category);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Slog.w(TAG, e.getCause());
+ synchronized (mLock) {
+ // Launch a dock activity
+ String category;
+ if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
+ // Only launch car home when car mode is enabled.
+ category = Intent.CATEGORY_CAR_DOCK;
+ } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) {
+ category = Intent.CATEGORY_DESK_DOCK;
+ } else {
+ category = null;
+ }
+ if (category != null) {
+ intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(category);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Slog.w(TAG, e.getCause());
+ }
+ }
+
+ if (mHoldingConfiguration) {
+ mHoldingConfiguration = false;
+ updateConfigurationLocked();
}
}
}
@@ -370,42 +379,46 @@
}
}
+ final void updateConfigurationLocked() {
+ int uiMode = 0;
+ if (mCarModeEnabled) {
+ uiMode = Configuration.UI_MODE_TYPE_CAR;
+ } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+ uiMode = Configuration.UI_MODE_TYPE_DESK;
+ }
+ if (uiMode != 0) {
+ if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
+ updateTwilightLocked();
+ uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
+ : Configuration.UI_MODE_NIGHT_NO;
+ } else {
+ uiMode |= mNightMode << 4;
+ }
+ } else {
+ // Disabling the car mode clears the night mode.
+ uiMode = Configuration.UI_MODE_TYPE_NORMAL |
+ Configuration.UI_MODE_NIGHT_NO;
+ }
+
+ mCurUiMode = uiMode;
+
+ if (!mHoldingConfiguration && uiMode != mSetUiMode) {
+ mSetUiMode = uiMode;
+
+ try {
+ final IActivityManager am = ActivityManagerNative.getDefault();
+ mConfiguration.uiMode = uiMode;
+ am.updateConfiguration(mConfiguration);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failure communicating with activity manager", e);
+ }
+ }
+ }
+
final void updateLocked() {
long ident = Binder.clearCallingIdentity();
try {
- int uiMode = 0;
- if (mCarModeEnabled) {
- uiMode = Configuration.UI_MODE_TYPE_CAR;
- } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
- uiMode = Configuration.UI_MODE_TYPE_DESK;
- }
- if (uiMode != 0) {
- if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
- updateTwilightLocked();
- uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
- : Configuration.UI_MODE_NIGHT_NO;
- } else {
- uiMode |= mNightMode << 4;
- }
- } else {
- // Disabling the car mode clears the night mode.
- uiMode = Configuration.UI_MODE_TYPE_NORMAL |
- Configuration.UI_MODE_NIGHT_NO;
- }
-
- if (uiMode != mCurUiMode) {
- mCurUiMode = uiMode;
-
- try {
- final IActivityManager am = ActivityManagerNative.getDefault();
- mConfiguration.uiMode = uiMode;
- am.updateConfiguration(mConfiguration);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failure communicating with activity manager", e);
- }
- }
-
String action = null;
String oldAction = null;
if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
@@ -450,7 +463,13 @@
// placed into a dock.
mContext.sendOrderedBroadcast(new Intent(action), null,
mResultReceiver, null, Activity.RESULT_OK, null, null);
+ // Attempting to make this transition a little more clean, we are going
+ // to hold off on doing a configuration change until we have finished
+ // the broacast and started the home activity.
+ mHoldingConfiguration = true;
}
+
+ updateConfigurationLocked();
// keep screen on when charging and in car mode
boolean keepScreenOn = mCharging &&
@@ -685,6 +704,8 @@
pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
pw.print(" mComputedNightMode="); pw.println(mComputedNightMode);
pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode));
+ pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
+ pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration);
pw.print(" mSystemReady="); pw.println(mSystemReady);
if (mLocation != null) {
pw.print(" mLocation="); pw.println(mLocation);
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 62263a6..248f579 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -96,7 +96,6 @@
private final WifiStateTracker mWifiStateTracker;
private Context mContext;
- private int mWifiState;
private int mWifiApState;
private AlarmManager mAlarmManager;
@@ -216,7 +215,7 @@
wifiThread.start();
mWifiHandler = new WifiHandler(wifiThread.getLooper());
- mWifiState = WIFI_STATE_DISABLED;
+ mWifiStateTracker.setWifiState(WIFI_STATE_DISABLED);
mWifiApState = WIFI_AP_STATE_DISABLED;
boolean wifiEnabled = getPersistedWifiEnabled();
boolean wifiAPEnabled = wifiEnabled ? false : getPersistedWifiApEnabled();
@@ -406,8 +405,9 @@
*/
private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid) {
final int eventualWifiState = enable ? WIFI_STATE_ENABLED : WIFI_STATE_DISABLED;
+ final int wifiState = mWifiStateTracker.getWifiState();
- if (mWifiState == eventualWifiState) {
+ if (wifiState == eventualWifiState) {
return true;
}
if (enable && isAirplaneModeOn() && !mAirplaneModeOverwridden) {
@@ -421,7 +421,7 @@
* Avoid doing a disable when the current Wifi state is UNKNOWN
* TODO: Handle driver load fail and supplicant lost as seperate states
*/
- if ((mWifiState == WIFI_STATE_UNKNOWN) && !enable) {
+ if ((wifiState == WIFI_STATE_UNKNOWN) && !enable) {
return false;
}
@@ -489,7 +489,7 @@
}
private void setWifiEnabledState(int wifiState, int uid) {
- final int previousWifiState = mWifiState;
+ final int previousWifiState = mWifiStateTracker.getWifiState();
long ident = Binder.clearCallingIdentity();
try {
@@ -504,7 +504,7 @@
}
// Update state
- mWifiState = wifiState;
+ mWifiStateTracker.setWifiState(wifiState);
// Broadcast
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
@@ -541,7 +541,7 @@
*/
public int getWifiEnabledState() {
enforceAccessPermission();
- return mWifiState;
+ return mWifiStateTracker.getWifiState();
}
/**
@@ -639,7 +639,7 @@
setWifiApEnabledState(enable ? WIFI_AP_STATE_ENABLING : WIFI_AP_STATE_DISABLING, uid);
- if (enable && (mWifiState == WIFI_STATE_ENABLED)) {
+ if (enable && (mWifiStateTracker.getWifiState() == WIFI_STATE_ENABLED)) {
setWifiEnabledBlocking(false, true, Process.myUid());
}
@@ -1721,7 +1721,7 @@
}
synchronized (mWifiHandler) {
- if (mWifiState == WIFI_STATE_ENABLING && !airplaneMode) {
+ if ((mWifiStateTracker.getWifiState() == WIFI_STATE_ENABLING) && !airplaneMode) {
return;
}
if (wifiShouldBeEnabled) {
@@ -1864,7 +1864,7 @@
+ ", uid=" + Binder.getCallingUid());
return;
}
- pw.println("Wi-Fi is " + stateName(mWifiState));
+ pw.println("Wi-Fi is " + stateName(mWifiStateTracker.getWifiState()));
pw.println("Stay-awake conditions: " +
Settings.System.getInt(mContext.getContentResolver(),
Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0));
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 34a7fc0..989fe2a 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -43,6 +43,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.policy.PolicyManager;
+import com.android.internal.policy.impl.PhoneWindowManager;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
@@ -984,10 +985,15 @@
//Slog.i(TAG, "Placing input method @" + (i+1));
if (w != null) {
if (willMove) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
- if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from "
- + mInputMethodTarget + " to " + w, e);
+ if (DEBUG_INPUT_METHOD) {
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ Slog.w(TAG, "Moving IM target from "
+ + mInputMethodTarget + " to " + w, e);
+ }
mInputMethodTarget = w;
if (w.mAppToken != null) {
setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment);
@@ -998,10 +1004,15 @@
return i+1;
}
if (willMove) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
- if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from "
- + mInputMethodTarget + " to null", e);
+ if (DEBUG_INPUT_METHOD) {
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ Slog.w(TAG, "Moving IM target from "
+ + mInputMethodTarget + " to null", e);
+ }
mInputMethodTarget = null;
setInputMethodAnimLayerAdjustment(0);
}
@@ -2178,6 +2189,16 @@
}
}
+ private static void logSurface(WindowState w, String msg, RuntimeException where) {
+ String str = " SURFACE " + Integer.toHexString(w.hashCode())
+ + ": " + msg + " / " + w.mAttrs.getTitle();
+ if (where != null) {
+ Slog.i(TAG, str, where);
+ } else {
+ Slog.i(TAG, str);
+ }
+ }
+
private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
long origId = Binder.clearCallingIdentity();
try {
@@ -2187,9 +2208,8 @@
if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION");
Surface.openTransaction();
try {
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " SURFACE " + w.mSurface
- + ": transparentRegionHint=" + region);
+ if (SHOW_TRANSACTIONS) logSurface(w,
+ "transparentRegionHint=" + region, null);
w.mSurface.setTransparentRegionHint(region);
} finally {
if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION");
@@ -2654,8 +2674,11 @@
+ " isEntrance=" + isEntrance);
if (a != null) {
if (DEBUG_ANIM) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
Slog.v(TAG, "Loaded animation " + a + " for " + win, e);
}
win.setAnimation(a);
@@ -2777,8 +2800,11 @@
}
if (a != null) {
if (DEBUG_ANIM) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e);
}
wtoken.setAnimation(a);
@@ -3569,8 +3595,11 @@
}
if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
+ "): mNextAppTransition=" + mNextAppTransition
+ " hidden=" + wtoken.hidden
@@ -3671,8 +3700,11 @@
public void startAppFreezingScreenLocked(AppWindowToken wtoken,
int configChanges) {
if (DEBUG_ORIENTATION) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
Slog.i(TAG, "Set freezing of " + wtoken.appToken
+ ": hidden=" + wtoken.hidden + " freezing="
+ wtoken.freezingScreen, e);
@@ -7305,7 +7337,8 @@
+ mSession.mSurfaceSession
+ ": pid=" + mSession.mPid + " format="
+ mAttrs.format + " flags=0x"
- + Integer.toHexString(flags));
+ + Integer.toHexString(flags)
+ + " / " + this);
} catch (Surface.OutOfResourcesException e) {
Slog.w(TAG, "OutOfResourcesException creating surface");
reclaimSomeSurfaceMemoryLocked(this, "create");
@@ -7321,11 +7354,10 @@
+ ", animLayer=" + mAnimLayer);
if (SHOW_TRANSACTIONS) {
Slog.i(TAG, ">>> OPEN TRANSACTION");
- Slog.i(TAG, " SURFACE " + mSurface + ": CREATE ("
- + mAttrs.getTitle() + ") pos=(" +
- mFrame.left + "," + mFrame.top + ") (" +
- mFrame.width() + "x" + mFrame.height() + "), layer=" +
- mAnimLayer + " HIDE");
+ if (SHOW_TRANSACTIONS) logSurface(this,
+ "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
+ mFrame.width() + "x" + mFrame.height() + "), layer=" +
+ mAnimLayer + " HIDE", null);
}
Surface.openTransaction();
try {
@@ -7335,8 +7367,7 @@
mSurface.setLayer(mAnimLayer);
mSurface.hide();
if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " SURFACE "
- + mSurface + ": DITHER");
+ if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
mSurface.setFlags(Surface.SURFACE_DITHER,
Surface.SURFACE_DITHER);
}
@@ -7393,16 +7424,21 @@
try {
if (DEBUG_VISIBILITY) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
Slog.w(TAG, "Window " + this + " destroying surface "
+ mSurface + ", session " + mSession, e);
}
if (SHOW_TRANSACTIONS) {
- RuntimeException ex = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) ex.fillInStackTrace();
- Slog.i(TAG, " SURFACE " + mSurface + ": DESTROY ("
- + mAttrs.getTitle() + ")", ex);
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
}
mSurface.destroy();
} catch (RuntimeException e) {
@@ -7445,15 +7481,18 @@
// This must be called while inside a transaction.
boolean performShowLocked() {
if (DEBUG_VISIBILITY) {
- RuntimeException e = new RuntimeException();
- if (!HIDE_STACK_CRAWLS) e.fillInStackTrace();
+ RuntimeException e = null;
+ if (!HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
Slog.v(TAG, "performShow on " + this
+ ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
+ " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
}
if (mReadyToShow && isReadyForDisplay()) {
- if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.i(
- TAG, " SURFACE " + mSurface + ": SHOW (performShowLocked)");
+ if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
+ "SHOW (performShowLocked)", null);
if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
+ " during animation: policyVis=" + mPolicyVisibility
+ " attHidden=" + mAttachedHidden
@@ -7666,8 +7705,7 @@
if (mSurface != null) {
mDestroySurface.add(this);
mDestroying = true;
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " SURFACE " + mSurface + ": HIDE (finishExit)");
+ if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
try {
mSurface.hide();
} catch (RuntimeException e) {
@@ -7826,6 +7864,7 @@
final AppWindowToken atoken = mAppToken;
return mSurface != null && !mAttachedHidden
&& (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
+ && !mDrawPending && !mCommitDrawPending
&& !mExiting && !mDestroying;
}
@@ -8045,6 +8084,18 @@
return false;
}
if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
+ if (doAnimation) {
+ if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
+ + mPolicyVisibility + " mAnimation=" + mAnimation);
+ if (mDisplayFrozen || !mPolicy.isScreenOn()) {
+ doAnimation = false;
+ } else if (mPolicyVisibility && mAnimation == null) {
+ // Check for the case where we are currently visible and
+ // not animating; we do not want to do animation at such a
+ // point to become visible when we already are.
+ doAnimation = false;
+ }
+ }
mPolicyVisibility = true;
mPolicyVisibilityAfterAnim = true;
if (doAnimation) {
@@ -8061,6 +8112,11 @@
}
boolean hideLw(boolean doAnimation, boolean requestAnim) {
+ if (doAnimation) {
+ if (mDisplayFrozen || !mPolicy.isScreenOn()) {
+ doAnimation = false;
+ }
+ }
boolean current = doAnimation ? mPolicyVisibilityAfterAnim
: mPolicyVisibility;
if (!current) {
@@ -8082,6 +8138,9 @@
// for it to be displayed before enabling the display, that
// we allow the display to be enabled now.
enableScreenIfNeededLocked();
+ if (mCurrentFocus == this) {
+ mFocusMayChange = true;
+ }
}
if (requestAnim) {
requestAnimationLocked(0);
@@ -9283,131 +9342,106 @@
}
}
- private final void performLayoutLockedInner() {
+ private final int performLayoutLockedInner() {
+ if (!mLayoutNeeded) {
+ return 0;
+ }
+
+ mLayoutNeeded = false;
+
final int dw = mDisplay.getWidth();
final int dh = mDisplay.getHeight();
final int N = mWindows.size();
- int repeats = 0;
int i;
if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed="
+ mLayoutNeeded + " dw=" + dw + " dh=" + dh);
- // FIRST LOOP: Perform a layout, if needed.
+ mPolicy.beginLayoutLw(dw, dh);
- while (mLayoutNeeded) {
- mPolicy.beginLayoutLw(dw, dh);
+ int seq = mLayoutSeq+1;
+ if (seq < 0) seq = 0;
+ mLayoutSeq = seq;
+
+ // First perform layout of any root windows (not attached
+ // to another window).
+ int topAttached = -1;
+ for (i = N-1; i >= 0; i--) {
+ WindowState win = (WindowState) mWindows.get(i);
- int seq = mLayoutSeq+1;
- if (seq < 0) seq = 0;
- mLayoutSeq = seq;
+ // Don't do layout of a window if it is not visible, or
+ // soon won't be visible, to avoid wasting time and funky
+ // changes while a window is animating away.
+ final AppWindowToken atoken = win.mAppToken;
+ final boolean gone = win.mViewVisibility == View.GONE
+ || !win.mRelayoutCalled
+ || win.mRootToken.hidden
+ || (atoken != null && atoken.hiddenRequested)
+ || win.mAttachedHidden
+ || win.mExiting || win.mDestroying;
+
+ if (!win.mLayoutAttached) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
+ + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
+ + " mLayoutAttached=" + win.mLayoutAttached);
+ if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
+ + win.mViewVisibility + " mRelayoutCalled="
+ + win.mRelayoutCalled + " hidden="
+ + win.mRootToken.hidden + " hiddenRequested="
+ + (atoken != null && atoken.hiddenRequested)
+ + " mAttachedHidden=" + win.mAttachedHidden);
+ }
- // First perform layout of any root windows (not attached
- // to another window).
- int topAttached = -1;
- for (i = N-1; i >= 0; i--) {
- WindowState win = (WindowState) mWindows.get(i);
-
- // Don't do layout of a window if it is not visible, or
- // soon won't be visible, to avoid wasting time and funky
- // changes while a window is animating away.
- final AppWindowToken atoken = win.mAppToken;
- final boolean gone = win.mViewVisibility == View.GONE
- || !win.mRelayoutCalled
- || win.mRootToken.hidden
- || (atoken != null && atoken.hiddenRequested)
- || win.mAttachedHidden
- || win.mExiting || win.mDestroying;
-
+ // If this view is GONE, then skip it -- keep the current
+ // frame, and let the caller know so they can ignore it
+ // if they want. (We do the normal layout for INVISIBLE
+ // windows, since that means "perform layout as normal,
+ // just don't display").
+ if (!gone || !win.mHaveFrame) {
if (!win.mLayoutAttached) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win
- + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
- + " mLayoutAttached=" + win.mLayoutAttached);
- if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility="
- + win.mViewVisibility + " mRelayoutCalled="
- + win.mRelayoutCalled + " hidden="
- + win.mRootToken.hidden + " hiddenRequested="
- + (atoken != null && atoken.hiddenRequested)
- + " mAttachedHidden=" + win.mAttachedHidden);
- }
-
- // If this view is GONE, then skip it -- keep the current
- // frame, and let the caller know so they can ignore it
- // if they want. (We do the normal layout for INVISIBLE
- // windows, since that means "perform layout as normal,
- // just don't display").
- if (!gone || !win.mHaveFrame) {
- if (!win.mLayoutAttached) {
- mPolicy.layoutWindowLw(win, win.mAttrs, null);
- win.mLayoutSeq = seq;
- if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
- + win.mFrame + " mContainingFrame="
- + win.mContainingFrame + " mDisplayFrame="
- + win.mDisplayFrame);
- } else {
- if (topAttached < 0) topAttached = i;
- }
- }
- }
-
- // Now perform layout of attached windows, which usually
- // depend on the position of the window they are attached to.
- // XXX does not deal with windows that are attached to windows
- // that are themselves attached.
- for (i = topAttached; i >= 0; i--) {
- WindowState win = (WindowState) mWindows.get(i);
-
- // If this view is GONE, then skip it -- keep the current
- // frame, and let the caller know so they can ignore it
- // if they want. (We do the normal layout for INVISIBLE
- // windows, since that means "perform layout as normal,
- // just don't display").
- if (win.mLayoutAttached) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
- + " mHaveFrame=" + win.mHaveFrame
- + " mViewVisibility=" + win.mViewVisibility
- + " mRelayoutCalled=" + win.mRelayoutCalled);
- if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
- || !win.mHaveFrame) {
- mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
- win.mLayoutSeq = seq;
- if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
- + win.mFrame + " mContainingFrame="
- + win.mContainingFrame + " mDisplayFrame="
- + win.mDisplayFrame);
- }
- }
- }
-
- int changes = mPolicy.finishLayoutLw();
- if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
- if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
- assignLayersLocked();
- }
- }
- if (changes == 0) {
- mLayoutNeeded = false;
- } else if (repeats > 2) {
- Slog.w(TAG, "Layout repeat aborted after too many iterations");
- mLayoutNeeded = false;
- if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
- if (updateOrientationFromAppTokensLocked()) {
- mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
- }
- }
- } else {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Repeating layout because changes=0x"
- + Integer.toHexString(changes));
- repeats++;
- if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
- if (updateOrientationFromAppTokensLocked()) {
- mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
- }
+ mPolicy.layoutWindowLw(win, win.mAttrs, null);
+ win.mLayoutSeq = seq;
+ if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
+ + win.mFrame + " mContainingFrame="
+ + win.mContainingFrame + " mDisplayFrame="
+ + win.mDisplayFrame);
+ } else {
+ if (topAttached < 0) topAttached = i;
}
}
}
+
+ // Now perform layout of attached windows, which usually
+ // depend on the position of the window they are attached to.
+ // XXX does not deal with windows that are attached to windows
+ // that are themselves attached.
+ for (i = topAttached; i >= 0; i--) {
+ WindowState win = (WindowState) mWindows.get(i);
+
+ // If this view is GONE, then skip it -- keep the current
+ // frame, and let the caller know so they can ignore it
+ // if they want. (We do the normal layout for INVISIBLE
+ // windows, since that means "perform layout as normal,
+ // just don't display").
+ if (win.mLayoutAttached) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win
+ + " mHaveFrame=" + win.mHaveFrame
+ + " mViewVisibility=" + win.mViewVisibility
+ + " mRelayoutCalled=" + win.mRelayoutCalled);
+ if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
+ || !win.mHaveFrame) {
+ mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
+ win.mLayoutSeq = seq;
+ if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame="
+ + win.mFrame + " mContainingFrame="
+ + win.mContainingFrame + " mDisplayFrame="
+ + win.mDisplayFrame);
+ }
+ }
+ }
+
+ return mPolicy.finishLayoutLw();
}
private final void performLayoutAndPlaceSurfacesLockedInner(
@@ -9423,9 +9457,6 @@
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
}
- // FIRST LOOP: Perform a layout, if needed.
- performLayoutLockedInner();
-
if (mFxSession == null) {
mFxSession = new SurfaceSession();
}
@@ -9442,7 +9473,6 @@
mExitingAppTokens.get(i).hasVisible = false;
}
- // SECOND LOOP: Execute animations and update visibility of windows.
boolean orientationChangeComplete = true;
Session holdScreen = null;
float screenBrightness = -1;
@@ -9452,11 +9482,50 @@
Surface.openTransaction();
try {
- boolean restart;
- boolean forceHiding = false;
boolean wallpaperForceHidingChanged = false;
-
+ int repeats = 0;
+ int changes = 0;
+
do {
+ repeats++;
+ if (repeats > 6) {
+ Slog.w(TAG, "Animation repeat aborted after too many iterations");
+ mLayoutNeeded = false;
+ break;
+ }
+
+ if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER
+ | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG
+ | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
+ if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
+ if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
+ assignLayersLocked();
+ mLayoutNeeded = true;
+ }
+ }
+ if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
+ if (updateOrientationFromAppTokensLocked()) {
+ mLayoutNeeded = true;
+ mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+ }
+ }
+ if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+ mLayoutNeeded = true;
+ }
+ }
+
+ // FIRST LOOP: Perform a layout, if needed.
+ if (repeats < 4) {
+ changes = performLayoutLockedInner();
+ if (changes != 0) {
+ continue;
+ }
+ } else {
+ Slog.w(TAG, "Layout repeat skipped after too many iterations");
+ changes = 0;
+ }
+
final int transactionSequence = ++mTransactionSequence;
// Update animations of all applications, including those
@@ -9475,15 +9544,17 @@
}
}
+ // SECOND LOOP: Execute animations and update visibility of windows.
+
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
+ transactionSequence + " tokensAnimating="
+ tokensAnimating);
animating = tokensAnimating;
- restart = false;
boolean tokenMayBeDrawn = false;
boolean wallpaperMayChange = false;
+ boolean forceHiding = false;
mPolicy.beginAnimationLw(dw, dh);
@@ -9536,7 +9607,7 @@
"Now policy shown: " + w);
if (changed) {
if (wallpaperForceHidingChanged
- && w.isReadyForDisplay()) {
+ && w.isVisibleNow() /*w.isReadyForDisplay()*/) {
// Assume we will need to animate. If
// we don't (because the wallpaper will
// stay with the lock screen), then we will
@@ -9609,9 +9680,7 @@
}
}
- if (mPolicy.finishAnimationLw()) {
- restart = true;
- }
+ changes |= mPolicy.finishAnimationLw();
if (tokenMayBeDrawn) {
// See if any windows have been drawn, so they (and others
@@ -9641,7 +9710,7 @@
+ " interesting=" + numInteresting
+ " drawn=" + wtoken.numDrawnWindows);
wtoken.allDrawn = true;
- restart = true;
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
// We can now show all of the drawn windows!
if (!mOpeningApps.contains(wtoken)) {
@@ -9856,15 +9925,13 @@
// This has changed the visibility of windows, so perform
// a new layout to get them all up-to-date.
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
mLayoutNeeded = true;
if (!moveInputMethodWindowsIfNeededLocked(true)) {
assignLayersLocked();
}
- performLayoutLockedInner();
updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES);
mFocusMayChange = false;
-
- restart = true;
}
}
@@ -9880,10 +9947,9 @@
mToBottomApps.clear();
rebuildAppWindowListLocked();
- restart = true;
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
moveInputMethodWindowsIfNeededLocked(false);
wallpaperMayChange = true;
- mLayoutNeeded = true;
// Since the window list has been rebuilt, focus might
// have to be recomputed since the actual order of windows
// might have changed again.
@@ -9892,7 +9958,7 @@
int adjResult = 0;
- if (wallpaperForceHidingChanged && !restart && !mAppTransitionReady) {
+ if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
// At this point, there was a window with a wallpaper that
// was force hiding other windows behind it, but now it
// is going away. This may be simple -- just animate
@@ -9913,7 +9979,7 @@
// actually started the animation... let's completely
// re-evaluate everything.
mLowerWallpaperTarget = mUpperWallpaperTarget = null;
- restart = true;
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
}
}
adjResult = adjustWallpaperWindowsLocked();
@@ -9954,33 +10020,30 @@
if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
if (DEBUG_WALLPAPER) Slog.v(TAG,
"Wallpaper layer changed: assigning layers + relayout");
- restart = true;
- mLayoutNeeded = true;
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
assignLayersLocked();
} else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
if (DEBUG_WALLPAPER) Slog.v(TAG,
"Wallpaper visibility changed: relayout");
- restart = true;
- mLayoutNeeded = true;
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
}
if (mFocusMayChange) {
mFocusMayChange = false;
if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) {
- restart = true;
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
adjResult = 0;
}
}
if (mLayoutNeeded) {
- restart = true;
- performLayoutLockedInner();
+ changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: restart="
- + restart);
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x"
+ + Integer.toHexString(changes));
- } while (restart);
+ } while (changes != 0);
// THIRD LOOP: Update the surfaces of all windows.
@@ -10022,10 +10085,9 @@
w.mLastRequestedHeight = height;
w.mLastShownFrame.set(w.mShownFrame);
try {
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " SURFACE " + w.mSurface
- + ": POS " + w.mShownFrame.left
- + ", " + w.mShownFrame.top);
+ if (SHOW_TRANSACTIONS) logSurface(w,
+ "POS " + w.mShownFrame.left
+ + ", " + w.mShownFrame.top, null);
w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
} catch (RuntimeException e) {
Slog.w(TAG, "Error positioning surface in " + w, e);
@@ -10045,12 +10107,11 @@
if (height < 1) height = 1;
if (w.mSurface != null) {
try {
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " SURFACE " + w.mSurface + ": POS "
- + w.mShownFrame.left + ","
+ if (SHOW_TRANSACTIONS) logSurface(w,
+ "POS " + w.mShownFrame.left + ","
+ w.mShownFrame.top + " SIZE "
+ w.mShownFrame.width() + "x"
- + w.mShownFrame.height());
+ + w.mShownFrame.height(), null);
w.mSurface.setSize(width, height);
w.mSurface.setPosition(w.mShownFrame.left,
w.mShownFrame.top);
@@ -10136,8 +10197,8 @@
if (!w.mLastHidden) {
//dump();
w.mLastHidden = true;
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " SURFACE " + w.mSurface + ": HIDE (performLayout)");
+ if (SHOW_TRANSACTIONS) logSurface(w,
+ "HIDE (performLayout)", null);
if (w.mSurface != null) {
try {
w.mSurface.hide();
@@ -10176,13 +10237,12 @@
w.mLastDtDy = w.mDtDy;
w.mLastHScale = w.mHScale;
w.mLastVScale = w.mVScale;
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " SURFACE " + w.mSurface + ": alpha="
- + w.mShownAlpha + " layer=" + w.mAnimLayer
+ if (SHOW_TRANSACTIONS) logSurface(w,
+ "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer
+ " matrix=[" + (w.mDsDx*w.mHScale)
+ "," + (w.mDtDx*w.mVScale)
+ "][" + (w.mDsDy*w.mHScale)
- + "," + (w.mDtDy*w.mVScale) + "]");
+ + "," + (w.mDtDy*w.mVScale) + "]", null);
if (w.mSurface != null) {
try {
w.mSurface.setAlpha(w.mShownAlpha);
@@ -10201,8 +10261,8 @@
if (w.mLastHidden && !w.mDrawPending
&& !w.mCommitDrawPending
&& !w.mReadyToShow) {
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " SURFACE " + w.mSurface + ": SHOW (performLayout)");
+ if (SHOW_TRANSACTIONS) logSurface(w,
+ "SHOW (performLayout)", null);
if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
+ " during relayout");
if (showSurfaceRobustlyLocked(w)) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index b53100f..f6289ae 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -13226,9 +13226,11 @@
ac.updateConfiguration(mConfiguration);
}
- Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
- msg.obj = new Configuration(mConfiguration);
- mHandler.sendMessage(msg);
+ if (Settings.System.hasInterestingConfigurationChanges(changes)) {
+ Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
+ msg.obj = new Configuration(mConfiguration);
+ mHandler.sendMessage(msg);
+ }
for (int i=mLruProcesses.size()-1; i>=0; i--) {
ProcessRecord app = mLruProcesses.get(i);
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index e52cd47..ebd3314 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -33,6 +33,7 @@
import android.net.NetworkInfo;
import android.os.BatteryManager;
import android.os.Binder;
+import android.os.Environment;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Message;
@@ -72,7 +73,7 @@
private String[] mTetherableWifiRegexs;
private String[] mUpstreamIfaceRegexs;
- private HashMap<String, TetherInterfaceSM> mIfaces;
+ private HashMap<String, TetherInterfaceSM> mIfaces; // all tethered/tetherable ifaces
private BroadcastReceiver mStateReceiver;
@@ -86,14 +87,20 @@
private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
private static final String DNS_DEFAULT_SERVER2 = "4.2.2.2";
- private boolean mDunRequired;
+ private boolean mDunRequired; // configuration info - must use DUN apn on 3g
private boolean mUseHiPri;
+
private String mUpstreamIfaceName;
private HierarchicalStateMachine mTetherMasterSM;
private Notification mTetheredNotification;
+ // whether we can tether is the && of these two - they come in as separate
+ // broadcasts so track them so we can decide what to do when either changes
+ private boolean mUsbMassStorageOff; // track the status of USB Mass Storage
+ private boolean mUsbConnected; // track the status of USB connection
+
public Tethering(Context context) {
Log.d(TAG, "Tethering starting");
mContext = context;
@@ -117,6 +124,10 @@
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
+ filter.addAction(Intent.ACTION_MEDIA_SHARED);
+ filter.addAction(Intent.ACTION_MEDIA_UNSHARED);
+ mUsbMassStorageOff = !Environment.MEDIA_SHARED.equals(
+ Environment.getExternalStorageState());
mStateReceiver = new StateReceiver();
mContext.registerReceiver(mStateReceiver, filter);
@@ -381,17 +392,28 @@
}
}
+ private void updateUsbStatus() {
+ boolean enable = mUsbConnected && mUsbMassStorageOff;
+
+ if (mBooted) {
+ enableUsbIfaces(enable);
+ }
+ }
+
private class StateReceiver extends BroadcastReceiver {
public void onReceive(Context content, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- boolean usbConnected = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
+ mUsbConnected = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
== BatteryManager.BATTERY_PLUGGED_USB);
- if (mBooted) {
- Tethering.this.enableUsbIfaces(usbConnected); // add or remove them
- } else {
- mDeferedUsbConnection = usbConnected;
- }
+ Tethering.this.updateUsbStatus();
+ } else if (action.equals(Intent.ACTION_MEDIA_SHARED)) {
+ mUsbMassStorageOff = false;
+ updateUsbStatus();
+ }
+ else if (action.equals(Intent.ACTION_MEDIA_UNSHARED)) {
+ mUsbMassStorageOff = true;
+ updateUsbStatus();
} else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
@@ -409,9 +431,7 @@
} catch (RemoteException e) {}
} else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
mBooted = true;
- if (mDeferedUsbConnection) {
- Tethering.this.enableUsbIfaces(true);
- }
+ updateUsbStatus();
}
}
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index 0b69020..8c8b00c 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -16,6 +16,8 @@
package com.android.unit_tests;
+import com.android.internal.content.PackageHelper;
+
import android.os.storage.IMountService.Stub;
import android.net.Uri;
@@ -73,9 +75,9 @@
public final long MAX_WAIT_TIME=120*1000;
public final long WAIT_TIME_INCR=20*1000;
private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
- private static final int APP_INSTALL_AUTO = 0;
- private static final int APP_INSTALL_DEVICE = 1;
- private static final int APP_INSTALL_SDCARD = 2;
+ private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
+ private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL;
+ private static final int APP_INSTALL_SDCARD = PackageHelper.APP_INSTALL_EXTERNAL;
void failStr(String errMsg) {
Log.w(TAG, "errMsg="+errMsg);
@@ -315,9 +317,9 @@
if (!getInstallLoc(flags, expInstallLocation)) {
assertEquals(srcPath, appInstallPath);
assertEquals(publicSrcPath, appInstallPath);
- assertFalse((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
+ assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
} else {
- assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
+ assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX));
assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX));
}
@@ -1172,9 +1174,9 @@
ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
assertNotNull(info);
if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
- assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) == 0);
+ assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
} else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
- assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
+ assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
}
} else {
assertFalse(retCode);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 85665e0..ab5e937 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -13,7 +13,6 @@
#include <stdarg.h>
#define NOISY(x) //x
-#define NOISY_REF(x) //x
status_t compileXmlFile(const sp<AaptAssets>& assets,
const sp<AaptFile>& target,
@@ -1934,7 +1933,7 @@
// information we have already processed that string!
outValue->size = sizeof(Res_value);
outValue->res0 = 0;
- outValue->dataType = Res_value::TYPE_STRING;
+ outValue->dataType = outValue->TYPE_STRING;
outValue->data = 0;
finalStr = str;
}
@@ -1943,7 +1942,7 @@
return false;
}
- if (outValue->dataType == Res_value::TYPE_STRING) {
+ if (outValue->dataType == outValue->TYPE_STRING) {
// Should do better merging styles.
if (pool) {
if (style != NULL && style->size() > 0) {
@@ -2531,7 +2530,6 @@
// Iterate through all data, collecting all values (strings,
// references, etc).
StringPool valueStrings = StringPool(false, bundle->getUTF8());
- ResourceConfigReferences configRefs;
for (pi=0; pi<N; pi++) {
sp<Package> p = mOrderedPackages.itemAt(pi);
if (p->getTypes().size() == 0) {
@@ -2572,13 +2570,6 @@
if (err != NO_ERROR) {
return err;
}
- if (e->getType() == Entry::TYPE_ITEM) {
- const Item* item = e->getItem();
- if (item != NULL) {
- uint32_t poolIndex = item->parsedValue.data;
- configRefs.add(poolIndex, config);
- }
- }
}
}
}
@@ -2587,70 +2578,6 @@
p->setKeyStrings(keyStrings.createStringBlock());
}
- NOISY_REF(configRefs.dump();)
-
- // Trim all entries in config tables that are not roots for that string.
- // i.e., rely on the resource system to grab the string from the more
- // generic pool during runtime to save space.
- for (pi=0; pi<N; pi++) {
- sp<Package> p = mOrderedPackages.itemAt(pi);
- if (p->getTypes().size() == 0) {
- // Empty, skip!
- continue;
- }
- const size_t TN = p->getOrderedTypes().size();
- for (size_t ti=0; ti<TN; ti++) {
- sp<Type> t = p->getOrderedTypes().itemAt(ti);
- if (t == NULL) {
- continue;
- }
- size_t CN = t->getOrderedConfigs().size();
- for (size_t ci=0; ci<CN; ci++) {
- sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci);
- if (c == NULL) {
- continue;
- }
- DefaultKeyedVector<ConfigDescription, sp<Entry> > newEntries;
- size_t EN = c->getEntries().size();
- for (size_t ei=0; ei<EN; ++ei) {
- ConfigDescription config = c->getEntries().keyAt(ei);
- if (!filter.match(config)) {
- continue;
- }
- sp<Entry> e = c->getEntries().valueAt(ei);
- if (e == NULL) {
- continue;
- }
- if (e->getType() == Entry::TYPE_ITEM) {
- const Item* item = e->getItem();
- if (item != NULL) {
- uint32_t poolIndex = item->parsedValue.data;
- if (!configRefs.isRoot(poolIndex, config)) {
- NOISY_REF(
- printf(" ConfigRef %d: removing ", poolIndex);
- DEBUG_LANG(config)
- printf("\n");
- )
- c->removeEntryAt(ei);
- t->removeUniqueConfig(config);
- --ei; --EN;
- }
- }
- }
- }
- if (EN == 0) {
- // We removed all the entries from a config, so remove the
- // config itself.
- NOISY_REF(
- printf(" ConfigRef REMOVED ENTIRE CONFIG\n");
- )
- t->removeOrderedConfigAt(ci);
- --ci; --CN;
- }
- }
- }
- }
-
ssize_t strAmt = 0;
// Now build the array of package chunks.
@@ -3805,95 +3732,3 @@
}
return res;
}
-
-#define DEBUG_LANG(x) printf("lang=%c%c cnt=%c%c ", \
- (x).language[0] ? (x).language[0] : '-', \
- (x).language[1] ? (x).language[1] : '-', \
- (x).country[0] ? (x).country[0] : '-', \
- (x).country[1] ? (x).country[1] : '-');
-
-status_t ResourceConfigReferences::add(uint32_t id, const ResTable_config& config)
-{
- ssize_t index = mRoots.indexOfKey(id);
- if (index < 0) {
- index = mRoots.add(id, Vector<const ResTable_config*>());
- }
- Vector<const ResTable_config*>& configRoots = mRoots.editValueFor(id);
-
- if (!configRoots.isEmpty()) {
- ssize_t NR = configRoots.size();
- for (int ri=0; ri<NR; ++ri) {
- const ResTable_config* current = configRoots[ri];
-
- if (config.match(*current)) {
- // We already have something more generic than our incoming string.
- NOISY_REF(
- printf(" ConfigRef %d: ignoring ", id);
- DEBUG_LANG(config)
- printf("\n");
- )
- return NO_ERROR;
- } else if (current->match(config)) {
- // more generic
- NOISY_REF(
- printf(" ConfigRef %d: remove ", id);
- DEBUG_LANG(current)
- printf("\n");
- )
- configRoots.removeItemsAt(ri);
- --ri; --NR;
- }
- }
- }
- NOISY_REF(
- printf(" ConfigRef %d: add ", id);
- DEBUG_LANG(config)
- printf("\n");
- )
- ResTable_config *configCopy = (ResTable_config*)malloc(sizeof(ResTable_config));
- memcpy(configCopy, &config, sizeof(ResTable_config));
- configRoots.add(configCopy);
-
- return NO_ERROR;
-}
-
-void ResourceConfigReferences::dump()
-{
- printf("ResourceConfigReferences\n");
- const ssize_t NR = mRoots.size();
- for (int ri=0; ri<NR; ++ri) {
- const Vector<const ResTable_config*>& configRoots = mRoots.valueAt(ri);
- printf(" String %d\n", mRoots.keyAt(ri));
- const ssize_t NC = configRoots.size();
- for (int ci=0; ci<NC; ++ci) {
- printf(" ");
- DEBUG_LANG(*configRoots[ci])
- printf("\n");
- }
- }
-}
-
-bool ResourceConfigReferences::isRoot(uint32_t id, const ResTable_config& config)
-{
- const Vector<const ResTable_config*>& configRoots = mRoots.editValueFor(id);
- const ssize_t NR = configRoots.size();
- for (int ri = 0; ri<NR; ++ri) {
- if (configRoots[ri]->match(config)) {
- return true;
- }
- }
- return false;
-}
-
-ResourceConfigReferences::~ResourceConfigReferences()
-{
- const ssize_t NR = mRoots.size();
- for (int ri=0; ri<NR; ++ri) {
- Vector<const ResTable_config*> configRoots = mRoots.editValueAt(ri);
- const ssize_t NC = configRoots.size();
- for (int ci=0; ci<NC; ++ci) {
- ResTable_config* config = const_cast<ResTable_config*>(configRoots[ci]);
- free(config);
- }
- }
-}
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index cc2a429..186c7ca 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -376,10 +376,6 @@
void addEntry(const ResTable_config& config, const sp<Entry>& entry) {
mEntries.add(config, entry);
}
-
- void removeEntryAt(int32_t index) {
- mEntries.removeItemsAt(index);
- }
const DefaultKeyedVector<ConfigDescription, sp<Entry> >& getEntries() const { return mEntries; }
private:
@@ -452,9 +448,6 @@
const DefaultKeyedVector<String16, sp<ConfigList> >& getConfigs() const { return mConfigs; }
const Vector<sp<ConfigList> >& getOrderedConfigs() const { return mOrderedConfigs; }
- void removeUniqueConfig(ConfigDescription& config) { mUniqueConfigs.remove(config); }
- void removeOrderedConfigAt(uint32_t index) { mOrderedConfigs.removeItemsAt(index); }
-
const SortedVector<String16>& getCanAddEntries() const { return mCanAddEntries; }
const SourcePos& getPos() const { return mPos; }
@@ -565,17 +558,5 @@
bool mContainsPseudo;
};
-class ResourceConfigReferences
-{
-public:
- ResourceConfigReferences() : mRoots() {}
- ~ResourceConfigReferences();
- status_t add(uint32_t id, const ResTable_config& config);
- bool isRoot(uint32_t id, const ResTable_config& config);
- void dump();
-
-private:
- KeyedVector<uint32_t, Vector<const ResTable_config*> > mRoots;
-};
#endif
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index cc47d08..9339428 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -16,6 +16,12 @@
package android.net.wifi;
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
+import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
+
import android.app.ActivityManagerNative;
import android.net.NetworkInfo;
import android.net.NetworkStateTracker;
@@ -270,6 +276,14 @@
private boolean mIsScanModeActive;
private boolean mEnableRssiPolling;
+ /**
+ * One of {@link WifiManager#WIFI_STATE_DISABLED},
+ * {@link WifiManager#WIFI_STATE_DISABLING},
+ * {@link WifiManager#WIFI_STATE_ENABLED},
+ * {@link WifiManager#WIFI_STATE_ENABLING},
+ * {@link WifiManager#WIFI_STATE_UNKNOWN}
+ */
+ private int mWifiState;
// Wi-Fi run states:
private static final int RUN_STATE_STARTING = 1;
private static final int RUN_STATE_RUNNING = 2;
@@ -771,9 +785,8 @@
case EVENT_SUPPLICANT_DISCONNECT:
mRunState = RUN_STATE_STOPPED;
noteRunState();
- int wifiState = mWM.getWifiState();
- boolean died = wifiState != WifiManager.WIFI_STATE_DISABLED &&
- wifiState != WifiManager.WIFI_STATE_DISABLING;
+ boolean died = mWifiState != WIFI_STATE_DISABLED &&
+ mWifiState != WIFI_STATE_DISABLING;
if (died) {
if (LOCAL_LOGD) Log.v(TAG, "Supplicant died unexpectedly");
} else {
@@ -1487,143 +1500,436 @@
return true;
}
- /**
- * TODO: add documentation to all the native calls
- * along with conditional checks to make sure
- * native calls dont happen when wifi is not enabled
+ public synchronized int getWifiState() {
+ return mWifiState;
+ }
+
+ public synchronized void setWifiState(int wifiState) {
+ mWifiState = wifiState;
+ }
+
+ /**
+ * The WifiNative interface functions are listed below.
+ * The only native call that is not synchronized on
+ * WifiStateTracker is waitForEvent() which waits on a
+ * seperate monitor channel.
+ *
+ * All supplicant commands need the wifi to be in an
+ * enabled state. This can be done by checking the
+ * mWifiState to be WIFI_STATE_ENABLED.
+ *
+ * All commands that can cause commands to driver
+ * initiated need the driver state to be started.
+ * This is done by checking isDriverStopped() to
+ * be false.
*/
+ /**
+ * Load the driver and firmware
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean loadDriver() {
return WifiNative.loadDriver();
}
+ /**
+ * Unload the driver and firmware
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean unloadDriver() {
return WifiNative.unloadDriver();
}
+ /**
+ * Check the supplicant config and
+ * start the supplicant daemon
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean startSupplicant() {
return WifiNative.startSupplicant();
}
+ /**
+ * Stop the supplicant daemon
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean stopSupplicant() {
return WifiNative.stopSupplicant();
}
+ /**
+ * Establishes two channels - control channel for commands
+ * and monitor channel for notifying WifiMonitor
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean connectToSupplicant() {
return WifiNative.connectToSupplicant();
}
+ /**
+ * Close the control/monitor channels to supplicant
+ */
public synchronized void closeSupplicantConnection() {
WifiNative.closeSupplicantConnection();
}
+ /**
+ * Check if the supplicant is alive
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean ping() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.pingCommand();
}
+ /**
+ * initiate an active or passive scan
+ *
+ * @param forceActive true if it is a active scan
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean scan(boolean forceActive) {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.scanCommand(forceActive);
}
+ /**
+ * Specifies whether the supplicant or driver
+ * take care of initiating scan and doing AP selection
+ *
+ * @param mode
+ * SUPPL_SCAN_HANDLING_NORMAL
+ * SUPPL_SCAN_HANDLING_LIST_ONLY
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean setScanResultHandling(int mode) {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.setScanResultHandlingCommand(mode);
}
+ /**
+ * Fetch the scan results from the supplicant
+ *
+ * @return example result string
+ * 00:bb:cc:dd:cc:ee 2427 166 [WPA-EAP-TKIP][WPA2-EAP-CCMP] Net1
+ * 00:bb:cc:dd:cc:ff 2412 165 [WPA-EAP-TKIP][WPA2-EAP-CCMP] Net2
+ */
public synchronized String scanResults() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return null;
+ }
return WifiNative.scanResultsCommand();
}
- public synchronized void setScanMode(boolean isScanModeActive) {
- if (mIsScanModeActive != isScanModeActive) {
- WifiNative.setScanModeCommand(mIsScanModeActive = isScanModeActive);
+ /**
+ * Set the scan mode - active or passive
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
+ public synchronized boolean setScanMode(boolean isScanModeActive) {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
}
+ if (mIsScanModeActive != isScanModeActive) {
+ return WifiNative.setScanModeCommand(mIsScanModeActive = isScanModeActive);
+ }
+ return true;
}
+ /**
+ * Disconnect from Access Point
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean disconnect() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.disconnectCommand();
}
+ /**
+ * Initiate a reconnection to AP
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean reconnectCommand() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.reconnectCommand();
}
+ /**
+ * Add a network
+ *
+ * @return network id of the new network
+ */
public synchronized int addNetwork() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return -1;
+ }
return WifiNative.addNetworkCommand();
}
+ /**
+ * Delete a network
+ *
+ * @param networkId id of the network to be removed
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean removeNetwork(int networkId) {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return mDisconnectExpected = WifiNative.removeNetworkCommand(networkId);
}
+ /**
+ * Enable a network
+ *
+ * @param netId network id of the network
+ * @param disableOthers true, if all other networks have to be disabled
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean enableNetwork(int netId, boolean disableOthers) {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.enableNetworkCommand(netId, disableOthers);
}
+ /**
+ * Disable a network
+ *
+ * @param netId network id of the network
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean disableNetwork(int netId) {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.disableNetworkCommand(netId);
}
+ /**
+ * Initiate a re-association in supplicant
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean reassociate() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.reassociateCommand();
}
+ /**
+ * Blacklist a BSSID. This will avoid the AP if there are
+ * alternate APs to connect
+ *
+ * @param bssid BSSID of the network
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean addToBlacklist(String bssid) {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.addToBlacklistCommand(bssid);
}
+ /**
+ * Clear the blacklist list
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean clearBlacklist() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.clearBlacklistCommand();
}
+ /**
+ * List all configured networks
+ *
+ * @return list of networks or null on failure
+ */
public synchronized String listNetworks() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return null;
+ }
return WifiNative.listNetworksCommand();
}
+ /**
+ * Get network setting by name
+ *
+ * @param netId network id of the network
+ * @param name network variable key
+ * @return value corresponding to key
+ */
public synchronized String getNetworkVariable(int netId, String name) {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return null;
+ }
return WifiNative.getNetworkVariableCommand(netId, name);
}
+ /**
+ * Set network setting by name
+ *
+ * @param netId network id of the network
+ * @param name network variable key
+ * @param value network variable value
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean setNetworkVariable(int netId, String name, String value) {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.setNetworkVariableCommand(netId, name, value);
}
+ /**
+ * Get detailed status of the connection
+ *
+ * @return Example status result
+ * bssid=aa:bb:cc:dd:ee:ff
+ * ssid=TestNet
+ * id=3
+ * pairwise_cipher=NONE
+ * group_cipher=NONE
+ * key_mgmt=NONE
+ * wpa_state=COMPLETED
+ * ip_address=X.X.X.X
+ */
public synchronized String status() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return null;
+ }
return WifiNative.statusCommand();
}
+ /**
+ * Get RSSI to currently connected network
+ *
+ * @return RSSI value, -1 on failure
+ */
public synchronized int getRssi() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return -1;
+ }
return WifiNative.getRssiApproxCommand();
}
+ /**
+ * Get approx RSSI to currently connected network
+ *
+ * @return RSSI value, -1 on failure
+ */
public synchronized int getRssiApprox() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return -1;
+ }
return WifiNative.getRssiApproxCommand();
}
+ /**
+ * Get link speed to currently connected network
+ *
+ * @return link speed, -1 on failure
+ */
public synchronized int getLinkSpeed() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return -1;
+ }
return WifiNative.getLinkSpeedCommand();
}
+ /**
+ * Get MAC address of radio
+ *
+ * @return MAC address, null on failure
+ */
public synchronized String getMacAddress() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return null;
+ }
return WifiNative.getMacAddressCommand();
}
+ /**
+ * Start driver
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean startDriver() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.startDriverCommand();
}
+ /**
+ * Stop driver
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean stopDriver() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.stopDriverCommand();
}
+ /**
+ * Start packet filtering
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean startPacketFiltering() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.startPacketFiltering();
}
+ /**
+ * Stop packet filtering
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean stopPacketFiltering() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.stopPacketFiltering();
}
+ /**
+ * Set power mode
+ * @param mode
+ * DRIVER_POWER_MODE_AUTO
+ * DRIVER_POWER_MODE_ACTIVE
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean setPowerMode(int mode) {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.setPowerModeCommand(mode);
}
@@ -1634,6 +1940,9 @@
* the number of channels is invalid.
*/
public synchronized boolean setNumAllowedChannels() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
try {
return setNumAllowedChannels(
Settings.Secure.getInt(mContext.getContentResolver(),
@@ -1656,15 +1965,38 @@
* {@code numChannels} is outside the valid range.
*/
public synchronized boolean setNumAllowedChannels(int numChannels) {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
mNumAllowedChannels = numChannels;
return WifiNative.setNumAllowedChannelsCommand(numChannels);
}
+ /**
+ * Get number of allowed channels
+ *
+ * @return channel count, -1 on failure
+ */
public synchronized int getNumAllowedChannels() {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return -1;
+ }
return WifiNative.getNumAllowedChannelsCommand();
}
+ /**
+ * Set bluetooth coex mode:
+ *
+ * @param mode
+ * BLUETOOTH_COEXISTENCE_MODE_ENABLED
+ * BLUETOOTH_COEXISTENCE_MODE_DISABLED
+ * BLUETOOTH_COEXISTENCE_MODE_SENSE
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean setBluetoothCoexistenceMode(int mode) {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return false;
+ }
return WifiNative.setBluetoothCoexistenceModeCommand(mode);
}
@@ -1676,14 +2008,33 @@
* @param isBluetoothPlaying whether to enable or disable this mode
*/
public synchronized void setBluetoothScanMode(boolean isBluetoothPlaying) {
+ if (mWifiState != WIFI_STATE_ENABLED && !isDriverStopped()) {
+ return;
+ }
WifiNative.setBluetoothCoexistenceScanModeCommand(isBluetoothPlaying);
}
+ /**
+ * Save configuration on supplicant
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean saveConfig() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.saveConfigCommand();
}
+ /**
+ * Reload the configuration from file
+ *
+ * @return {@code true} if the operation succeeds, {@code false} otherwise
+ */
public synchronized boolean reloadConfig() {
+ if (mWifiState != WIFI_STATE_ENABLED) {
+ return false;
+ }
return WifiNative.reloadConfigCommand();
}
@@ -1713,11 +2064,11 @@
@Override
public void interpretScanResultsAvailable() {
-
+
// If we shouldn't place a notification on available networks, then
// don't bother doing any of the following
if (!mNotificationEnabled) return;
-
+
NetworkInfo networkInfo = getNetworkInfo();
State state = networkInfo.getState();