1d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu/* 2d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * Copyright (C) 2013 The Android Open Source Project 3d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * 4d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * Licensed under the Apache License, Version 2.0 (the "License"); 5d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * you may not use this file except in compliance with the License. 6d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * You may obtain a copy of the License at 7d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * 8d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * http://www.apache.org/licenses/LICENSE-2.0 9d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * 10d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * Unless required by applicable law or agreed to in writing, software 11d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * distributed under the License is distributed on an "AS IS" BASIS, 12d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * See the License for the specific language governing permissions and 14d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu * limitations under the License. 15d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu */ 16d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 17d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescupackage com.android.gallery3d.ingest; 18d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 19d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.app.Activity; 20d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.app.ProgressDialog; 21d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.ComponentName; 22d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.Context; 23d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.Intent; 24d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.ServiceConnection; 25c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.content.res.Configuration; 26c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.database.DataSetObserver; 27d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.mtp.MtpObjectInfo; 28d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.Bundle; 29d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.Handler; 30d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.IBinder; 31d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.Message; 32c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.support.v4.view.ViewPager; 33d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.util.SparseBooleanArray; 34d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.ActionMode; 35d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.Menu; 36d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.MenuInflater; 37d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.MenuItem; 38d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.View; 39d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.widget.AbsListView.MultiChoiceModeListener; 40d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.widget.AdapterView; 41d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.widget.AdapterView.OnItemClickListener; 426516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescuimport android.widget.TextView; 43d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 44d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport com.android.gallery3d.R; 45c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.adapter.CheckBroker; 46d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport com.android.gallery3d.ingest.adapter.MtpAdapter; 47c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.adapter.MtpPagerAdapter; 48c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.data.MtpBitmapFetch; 49f63e1f7ab9a4f4a97909564cfc5975cbac66872fBobby Georgescuimport com.android.gallery3d.ingest.ui.DateTileView; 50c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.ui.IngestGridView; 51c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport com.android.gallery3d.ingest.ui.IngestGridView.OnClearChoicesListener; 52d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 53d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport java.lang.ref.WeakReference; 54d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport java.util.Collection; 55d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 56d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescupublic class IngestActivity extends Activity implements 57d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu MtpDeviceIndex.ProgressListener, ImportTask.Listener { 58d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 59d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private IngestService mHelperService; 60d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private boolean mActive = false; 61c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private IngestGridView mGridView; 62d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private MtpAdapter mAdapter; 63d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private Handler mHandler; 64d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private ProgressDialog mProgressDialog; 65d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private ActionMode mActiveActionMode; 66d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 67c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private View mWarningView; 68c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private TextView mWarningText; 69c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private int mLastCheckedPosition = 0; 70c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 71c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private ViewPager mFullscreenPager; 72c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private MtpPagerAdapter mPagerAdapter; 73c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private boolean mFullscreenPagerVisible = false; 74c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 75c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private MenuItem mMenuSwitcherItem; 76c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private MenuItem mActionMenuSwitcherItem; 776516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu 780c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu // The MTP framework components don't give us fine-grained file copy 790c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu // progress updates, so for large photos and videos, we will be stuck 800c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu // with a dialog not updating for a long time. To give the user feedback, 810c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu // we switch to the animated indeterminate progress bar after the timeout 820c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu // specified by INDETERMINATE_SWITCH_TIMEOUT_MS. On the next update from 830c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu // the framework, we switch back to the normal progress bar. 840c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu private static final int INDETERMINATE_SWITCH_TIMEOUT_MS = 3000; 850c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu 86d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 87d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu protected void onCreate(Bundle savedInstanceState) { 88d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu super.onCreate(savedInstanceState); 89d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu doBindHelperService(); 90d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 91d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu setContentView(R.layout.ingest_activity_item_list); 92c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mGridView = (IngestGridView) findViewById(R.id.ingest_gridview); 93d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mAdapter = new MtpAdapter(this); 94c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mAdapter.registerDataSetObserver(mMasterObserver); 95d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mGridView.setAdapter(mAdapter); 96d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mGridView.setMultiChoiceModeListener(mMultiChoiceModeListener); 97d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mGridView.setOnItemClickListener(mOnItemClickListener); 98c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mGridView.setOnClearChoicesListener(mPositionMappingCheckBroker); 99c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 100c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mFullscreenPager = (ViewPager) findViewById(R.id.ingest_view_pager); 101d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 102d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHandler = new ItemListHandler(this); 103c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 104c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu MtpBitmapFetch.configureForContext(this); 105d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 106d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 107d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private OnItemClickListener mOnItemClickListener = new OnItemClickListener() { 108d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 109d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onItemClick(AdapterView<?> adapterView, View itemView, int position, long arg3) { 110c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mLastCheckedPosition = position; 111d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mGridView.setItemChecked(position, !mGridView.getCheckedItemPositions().get(position)); 112d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 113d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu }; 114d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 115d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private MultiChoiceModeListener mMultiChoiceModeListener = new MultiChoiceModeListener() { 116d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private boolean mIgnoreItemCheckedStateChanges = false; 117d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 118d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private void updateSelectedTitle(ActionMode mode) { 119d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu int count = mGridView.getCheckedItemCount(); 120d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mode.setTitle(getResources().getQuantityString( 121d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu R.plurals.number_of_items_selected, count, count)); 122d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 123d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 124d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 125d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onItemCheckedStateChanged(ActionMode mode, int position, long id, 126d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu boolean checked) { 127d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mIgnoreItemCheckedStateChanges) return; 128d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mAdapter.itemAtPositionIsBucket(position)) { 129d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu SparseBooleanArray checkedItems = mGridView.getCheckedItemPositions(); 130d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mIgnoreItemCheckedStateChanges = true; 131d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mGridView.setItemChecked(position, false); 132d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 133d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Takes advantage of the fact that SectionIndexer imposes the 134d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // need to clamp to the valid range 135d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu int nextSectionStart = mAdapter.getPositionForSection( 136d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mAdapter.getSectionForPosition(position) + 1); 137d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (nextSectionStart == position) 138d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu nextSectionStart = mAdapter.getCount(); 139d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 140d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu boolean rangeValue = false; // Value we want to set all of the bucket items to 141d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 142d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Determine if all the items in the bucket are currently checked, so that we 143d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // can uncheck them, otherwise we will check all items in the bucket. 144d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu for (int i = position + 1; i < nextSectionStart; i++) { 145d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (checkedItems.get(i) == false) { 146d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu rangeValue = true; 147d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu break; 148d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 149d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 150d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 151d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Set all items in the bucket to the desired state 152d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu for (int i = position + 1; i < nextSectionStart; i++) { 153d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (checkedItems.get(i) != rangeValue) 154d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mGridView.setItemChecked(i, rangeValue); 155d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 156d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 157c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mPositionMappingCheckBroker.onBulkCheckedChange(); 158d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mIgnoreItemCheckedStateChanges = false; 159c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } else { 160c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mPositionMappingCheckBroker.onCheckedChange(position, checked); 161d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 162c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mLastCheckedPosition = position; 163d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu updateSelectedTitle(mode); 164d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 165d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 166d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 167d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 168c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return onOptionsItemSelected(item); 169d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 170d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 171d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 172d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public boolean onCreateActionMode(ActionMode mode, Menu menu) { 173d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu MenuInflater inflater = mode.getMenuInflater(); 174d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu inflater.inflate(R.menu.ingest_menu_item_list_selection, menu); 175d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu updateSelectedTitle(mode); 176d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mActiveActionMode = mode; 177c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mActionMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view); 178c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu setSwitcherMenuState(mActionMenuSwitcherItem, mFullscreenPagerVisible); 179d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu return true; 180d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 181d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 182d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 183d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onDestroyActionMode(ActionMode mode) { 184d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mActiveActionMode = null; 185c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mActionMenuSwitcherItem = null; 186c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_BULK_CHECKED_CHANGE); 187d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 188d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 189d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 190d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 191d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu updateSelectedTitle(mode); 192d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu return false; 193d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 194d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu }; 195d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 196c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public boolean onOptionsItemSelected(MenuItem item) { 197c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu switch (item.getItemId()) { 198c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu case R.id.import_items: 199c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mActiveActionMode != null) { 200c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mHelperService.importSelectedItems( 201c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mGridView.getCheckedItemPositions(), 202c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mAdapter); 203c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mActiveActionMode.finish(); 204c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 205c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return true; 206c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu case R.id.ingest_switch_view: 207c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu setFullscreenPagerVisibility(!mFullscreenPagerVisible); 208c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return true; 209c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu default: 210c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return false; 211c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 212c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 213c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 214c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 215c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public boolean onCreateOptionsMenu(Menu menu) { 216c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu MenuInflater inflater = getMenuInflater(); 217c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu inflater.inflate(R.menu.ingest_menu_item_list_selection, menu); 218c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view); 219c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu menu.findItem(R.id.import_items).setVisible(false); 220c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu setSwitcherMenuState(mMenuSwitcherItem, mFullscreenPagerVisible); 221c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return true; 222c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 223c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 224d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 225d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu protected void onDestroy() { 226d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu super.onDestroy(); 227d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu doUnbindHelperService(); 228d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 229d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 230d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 231d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu protected void onResume() { 232f63e1f7ab9a4f4a97909564cfc5975cbac66872fBobby Georgescu DateTileView.refreshLocale(); 233d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mActive = true; 234d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mHelperService != null) mHelperService.setClientActivity(this); 235c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu updateWarningView(); 236d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu super.onResume(); 237d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 238d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 239d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 240d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu protected void onPause() { 241d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mHelperService != null) mHelperService.setClientActivity(null); 242d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mActive = false; 243d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu cleanupProgressDialog(); 244d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu super.onPause(); 245d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 246d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 247c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 248c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public void onConfigurationChanged(Configuration newConfig) { 249c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu super.onConfigurationChanged(newConfig); 250c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu MtpBitmapFetch.configureForContext(this); 251c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 252c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 253c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private void showWarningView(int textResId) { 254c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mWarningView == null) { 255c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mWarningView = findViewById(R.id.ingest_warning_view); 256c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mWarningText = 257c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu (TextView)mWarningView.findViewById(R.id.ingest_warning_view_text); 2586516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 259c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mWarningText.setText(textResId); 260c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mWarningView.setVisibility(View.VISIBLE); 261c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu setFullscreenPagerVisibility(false); 2626516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu mGridView.setVisibility(View.GONE); 2636516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 2646516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu 265c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private void hideWarningView() { 266c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mWarningView != null) { 267c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mWarningView.setVisibility(View.GONE); 268c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu setFullscreenPagerVisibility(false); 2696516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 2706516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 2716516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu 272c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private PositionMappingCheckBroker mPositionMappingCheckBroker = new PositionMappingCheckBroker(); 273c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 274c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private class PositionMappingCheckBroker extends CheckBroker 275c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu implements OnClearChoicesListener { 276c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private int mLastMappingPager = -1; 277c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private int mLastMappingGrid = -1; 278c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 279c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private int mapPagerToGridPosition(int position) { 280c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (position != mLastMappingPager) { 281c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mLastMappingPager = position; 282c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mLastMappingGrid = mAdapter.translatePositionWithoutLabels(position); 283c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 284c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return mLastMappingGrid; 285c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 286c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 287c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private int mapGridToPagerPosition(int position) { 288c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (position != mLastMappingGrid) { 289c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mLastMappingGrid = position; 290c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mLastMappingPager = mPagerAdapter.translatePositionWithLabels(position); 291c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 292c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return mLastMappingPager; 293c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 294c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 295c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 296c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public void setItemChecked(int position, boolean checked) { 297c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mGridView.setItemChecked(mapPagerToGridPosition(position), checked); 298c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 299c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 300c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 301c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public void onCheckedChange(int position, boolean checked) { 302c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mPagerAdapter != null) { 303c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu super.onCheckedChange(mapGridToPagerPosition(position), checked); 304c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 305c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 306c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 307c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 308c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public boolean isItemChecked(int position) { 309c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return mGridView.getCheckedItemPositions().get(mapPagerToGridPosition(position)); 310c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 311c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 312c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 313c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public void onClearChoices() { 314c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu onBulkCheckedChange(); 315c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 316c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu }; 317c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 318c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private DataSetObserver mMasterObserver = new DataSetObserver() { 319c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 320c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public void onChanged() { 321c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mPagerAdapter != null) mPagerAdapter.notifyDataSetChanged(); 322c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 323c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 324c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 325c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public void onInvalidated() { 326c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mPagerAdapter != null) mPagerAdapter.notifyDataSetChanged(); 327c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 328c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu }; 329c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 330c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private int pickFullscreenStartingPosition() { 331c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu int firstVisiblePosition = mGridView.getFirstVisiblePosition(); 332c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mLastCheckedPosition <= firstVisiblePosition 333c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu || mLastCheckedPosition > mGridView.getLastVisiblePosition()) { 334c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return firstVisiblePosition; 335c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } else { 336c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return mLastCheckedPosition; 337c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 338c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 339c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 340c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private void setSwitcherMenuState(MenuItem menuItem, boolean inFullscreenMode) { 341c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (menuItem == null) return; 342c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (!inFullscreenMode) { 343c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu menuItem.setIcon(android.R.drawable.ic_menu_zoom); 344c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu menuItem.setTitle(R.string.switch_photo_fullscreen); 345c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } else { 346c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu menuItem.setIcon(android.R.drawable.ic_dialog_dialer); 347c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu menuItem.setTitle(R.string.switch_photo_grid); 348c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 349c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 350c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 351c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private void setFullscreenPagerVisibility(boolean visible) { 352c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mFullscreenPagerVisible = visible; 353c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (visible) { 354c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mPagerAdapter == null) { 355c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mPagerAdapter = new MtpPagerAdapter(this, mPositionMappingCheckBroker); 356c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mPagerAdapter.setMtpDeviceIndex(mAdapter.getMtpDeviceIndex()); 357c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 358c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mFullscreenPager.setAdapter(mPagerAdapter); 359c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mFullscreenPager.setCurrentItem(mPagerAdapter.translatePositionWithLabels( 360c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu pickFullscreenStartingPosition()), false); 361c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } else if (mPagerAdapter != null) { 362c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mGridView.setSelection(mAdapter.translatePositionWithoutLabels( 363c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mFullscreenPager.getCurrentItem())); 364c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mFullscreenPager.setAdapter(null); 365c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 366c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mGridView.setVisibility(visible ? View.INVISIBLE : View.VISIBLE); 367c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mFullscreenPager.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 368c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mActionMenuSwitcherItem != null) { 369c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu setSwitcherMenuState(mActionMenuSwitcherItem, visible); 370c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 371c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu setSwitcherMenuState(mMenuSwitcherItem, visible); 372c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 373c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 374c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private void updateWarningView() { 3756516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu if (!mAdapter.deviceConnected()) { 376c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu showWarningView(R.string.ingest_no_device); 3776516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } else if (mAdapter.indexReady() && mAdapter.getCount() == 0) { 378c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu showWarningView(R.string.ingest_empty_device); 3796516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } else { 380c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu hideWarningView(); 3816516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 3826516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 3836516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu 3846516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu private void UiThreadNotifyIndexChanged() { 385d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mAdapter.notifyDataSetChanged(); 386d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mActiveActionMode != null) { 387d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mActiveActionMode.finish(); 388d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mActiveActionMode = null; 389d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 390c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu updateWarningView(); 3916516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 3926516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu 3936516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu protected void notifyIndexChanged() { 3946516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED); 395d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 396d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 397d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private static class ProgressState { 398d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu String message; 399d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu String title; 400d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu int current; 401d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu int max; 402d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 403d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void reset() { 404d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu title = null; 405d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu message = null; 406d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu current = 0; 407d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu max = 0; 408d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 409d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 410d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 411d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private ProgressState mProgressState = new ProgressState(); 412d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 413d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 414d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onObjectIndexed(MtpObjectInfo object, int numVisited) { 415d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Not guaranteed to be called on the UI thread 416d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.reset(); 417d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.max = 0; 418d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.message = getResources().getQuantityString( 419d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu R.plurals.ingest_number_of_items_scanned, numVisited, numVisited); 420d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE); 421d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 422d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 423d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 424d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onSorting() { 425d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Not guaranteed to be called on the UI thread 426d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.reset(); 427d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.max = 0; 428d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.message = getResources().getString(R.string.ingest_sorting); 429d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE); 430d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 431d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 432d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 433d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onIndexFinish() { 434d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Not guaranteed to be called on the UI thread 435d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE); 4366516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED); 437d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 438d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 439d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 440d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onImportProgress(final int visitedCount, final int totalCount, 441d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu String pathIfSuccessful) { 442d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Not guaranteed to be called on the UI thread 443d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.reset(); 444d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.max = totalCount; 445d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.current = visitedCount; 446d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressState.title = getResources().getString(R.string.ingest_importing); 447d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE); 4480c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE); 4490c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu mHandler.sendEmptyMessageDelayed(ItemListHandler.MSG_PROGRESS_INDETERMINATE, 4500c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu INDETERMINATE_SWITCH_TIMEOUT_MS); 451d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 452d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 453d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 454384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu public void onImportFinish(Collection<MtpObjectInfo> objectsNotImported, 455384971f7ce93c98249825d0498ad4bcbd4104895Bobby Georgescu int numVisited) { 456d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // Not guaranteed to be called on the UI thread 457d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE); 4580c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE); 459d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // TODO: maybe show an extra dialog listing the ones that failed 460d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // importing, if any? 461d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 462d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 463d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private ProgressDialog getProgressDialog() { 464d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mProgressDialog == null || !mProgressDialog.isShowing()) { 465d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressDialog = new ProgressDialog(this); 466d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressDialog.setCancelable(false); 467d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 468d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu return mProgressDialog; 469d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 470d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 471d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private void updateProgressDialog() { 472d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu ProgressDialog dialog = getProgressDialog(); 473d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu boolean indeterminate = (mProgressState.max == 0); 474d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu dialog.setIndeterminate(indeterminate); 475d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu dialog.setProgressStyle(indeterminate ? ProgressDialog.STYLE_SPINNER 476d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu : ProgressDialog.STYLE_HORIZONTAL); 477d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mProgressState.title != null) { 478d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu dialog.setTitle(mProgressState.title); 479d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 480d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mProgressState.message != null) { 481d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu dialog.setMessage(mProgressState.message); 482d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 483d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (!indeterminate) { 484d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu dialog.setProgress(mProgressState.current); 485d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu dialog.setMax(mProgressState.max); 486d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 487d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (!dialog.isShowing()) { 488d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu dialog.show(); 489d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 490d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 491d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 4920c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu private void makeProgressDialogIndeterminate() { 4930c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu ProgressDialog dialog = getProgressDialog(); 4940c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu dialog.setIndeterminate(true); 4950c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu } 4960c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu 497d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private void cleanupProgressDialog() { 498d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mProgressDialog != null) { 499d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressDialog.hide(); 500d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mProgressDialog = null; 501d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 502d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 503d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 504d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu // This is static and uses a WeakReference in order to avoid leaking the Activity 505d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private static class ItemListHandler extends Handler { 506d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public static final int MSG_PROGRESS_UPDATE = 0; 507d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public static final int MSG_PROGRESS_HIDE = 1; 5086516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu public static final int MSG_NOTIFY_CHANGED = 2; 509c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public static final int MSG_BULK_CHECKED_CHANGE = 3; 5100c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu public static final int MSG_PROGRESS_INDETERMINATE = 4; 511d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 512d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu WeakReference<IngestActivity> mParentReference; 513d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 514d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public ItemListHandler(IngestActivity parent) { 515d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu super(); 516d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mParentReference = new WeakReference<IngestActivity>(parent); 517d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 518d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 519d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void handleMessage(Message message) { 520d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu IngestActivity parent = mParentReference.get(); 521d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (parent == null || !parent.mActive) 522d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu return; 523d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu switch (message.what) { 524d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu case MSG_PROGRESS_HIDE: 525d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu parent.cleanupProgressDialog(); 526d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu break; 527d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu case MSG_PROGRESS_UPDATE: 528d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu parent.updateProgressDialog(); 529d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu break; 5306516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu case MSG_NOTIFY_CHANGED: 5316516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu parent.UiThreadNotifyIndexChanged(); 532d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu break; 533c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu case MSG_BULK_CHECKED_CHANGE: 534c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu parent.mPositionMappingCheckBroker.onBulkCheckedChange(); 535c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu break; 5360c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu case MSG_PROGRESS_INDETERMINATE: 5370c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu parent.makeProgressDialogIndeterminate(); 5380c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu break; 539d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu default: 540d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu break; 541d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 542d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 543d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 544d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 545d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private ServiceConnection mHelperServiceConnection = new ServiceConnection() { 546d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onServiceConnected(ComponentName className, IBinder service) { 547d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHelperService = ((IngestService.LocalBinder) service).getService(); 548d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHelperService.setClientActivity(IngestActivity.this); 549c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu MtpDeviceIndex index = mHelperService.getIndex(); 550c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu mAdapter.setMtpDeviceIndex(index); 551c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (mPagerAdapter != null) mPagerAdapter.setMtpDeviceIndex(index); 552d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 553d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 554d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu public void onServiceDisconnected(ComponentName className) { 555d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHelperService = null; 556d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 557d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu }; 558d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 559d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private void doBindHelperService() { 560d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu bindService(new Intent(getApplicationContext(), IngestService.class), 561d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHelperServiceConnection, Context.BIND_AUTO_CREATE); 562d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 563d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 564d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu private void doUnbindHelperService() { 565d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu if (mHelperService != null) { 566d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu mHelperService.setClientActivity(null); 567d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu unbindService(mHelperServiceConnection); 568d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 569d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 570d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu} 571