diff options
-rw-r--r-- | cmds/stagefright/stagefright.cpp | 20 | ||||
-rw-r--r-- | core/java/android/accounts/AccountManagerService.java | 14 | ||||
-rw-r--r-- | core/java/android/content/SyncManager.java | 62 |
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, |