summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/stagefright/stagefright.cpp20
-rw-r--r--core/java/android/accounts/AccountManagerService.java14
-rw-r--r--core/java/android/content/SyncManager.java62
3 files changed, 79 insertions, 17 deletions
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 @@ static void usage(const char *me) {
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 @@ int main(int argc, char **argv) {
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 @@ public class AccountManagerService
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/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 @@ public class SyncManager implements OnAccountsUpdateListener {
*/
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 @@ public class SyncManager implements OnAccountsUpdateListener {
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 @@ public class SyncManager implements OnAccountsUpdateListener {
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 @@ public class SyncManager implements OnAccountsUpdateListener {
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 @@ public class SyncManager implements OnAccountsUpdateListener {
ISyncAdapter mSyncAdapter;
final long mStartTime;
long mTimeoutStartTime;
+ boolean mBound;
public ActiveSyncContext(SyncOperation syncOperation,
long historyRowId) {
@@ -895,15 +924,23 @@ public class SyncManager implements OnAccountsUpdateListener {
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 @@ public class SyncManager implements OnAccountsUpdateListener {
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 @@ public class SyncManager implements OnAccountsUpdateListener {
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 @@ public class SyncManager implements OnAccountsUpdateListener {
stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
upstreamActivity, downstreamActivity, elapsedTime);
- activeSyncContext.unBindFromSyncAdapter();
+ activeSyncContext.close();
if (syncResult != null && syncResult.tooManyDeletions) {
installHandleTooManyDeletesNotification(syncOperation.account,