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 19f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.R; 20f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.adapter.CheckBroker; 21f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.adapter.MtpAdapter; 22f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.adapter.MtpPagerAdapter; 23f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.data.ImportTask; 24f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.data.IngestObjectInfo; 25f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.data.MtpBitmapFetch; 26f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.data.MtpDeviceIndex; 27f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.ui.DateTileView; 28f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.ui.IngestGridView; 29f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport com.android.gallery3d.ingest.ui.IngestGridView.OnClearChoicesListener; 30f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 31f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport android.annotation.TargetApi; 32d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.app.Activity; 33d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.app.ProgressDialog; 34d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.ComponentName; 35d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.Context; 36d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.Intent; 37d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.content.ServiceConnection; 38c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.content.res.Configuration; 39c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.database.DataSetObserver; 40f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescuimport android.os.Build; 41d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.Bundle; 42d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.Handler; 43d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.IBinder; 44d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.os.Message; 45c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.support.v4.view.ViewPager; 46d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.util.SparseBooleanArray; 47d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.ActionMode; 48d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.Menu; 49d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.MenuInflater; 50d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.MenuItem; 51d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.view.View; 52d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.widget.AbsListView.MultiChoiceModeListener; 53d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.widget.AdapterView; 54d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport android.widget.AdapterView.OnItemClickListener; 556516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescuimport android.widget.TextView; 56d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 57d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport java.lang.ref.WeakReference; 58d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescuimport java.util.Collection; 59d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 60f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu/** 61f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu * MTP importer, main activity. 62f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu */ 63f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) 64d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescupublic class IngestActivity extends Activity implements 65f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu MtpDeviceIndex.ProgressListener, ImportTask.Listener { 66f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 67f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private IngestService mHelperService; 68f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private boolean mActive = false; 69f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private IngestGridView mGridView; 70f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private MtpAdapter mAdapter; 71f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private Handler mHandler; 72f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private ProgressDialog mProgressDialog; 73f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private ActionMode mActiveActionMode; 74f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 75f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private View mWarningView; 76f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private TextView mWarningText; 77f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private int mLastCheckedPosition = 0; 78f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 79f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private ViewPager mFullscreenPager; 80f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private MtpPagerAdapter mPagerAdapter; 81f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private boolean mFullscreenPagerVisible = false; 82f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 83f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private MenuItem mMenuSwitcherItem; 84f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private MenuItem mActionMenuSwitcherItem; 85f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 86f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // The MTP framework components don't give us fine-grained file copy 87f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // progress updates, so for large photos and videos, we will be stuck 88f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // with a dialog not updating for a long time. To give the user feedback, 89f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // we switch to the animated indeterminate progress bar after the timeout 90f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // specified by INDETERMINATE_SWITCH_TIMEOUT_MS. On the next update from 91f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // the framework, we switch back to the normal progress bar. 92f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private static final int INDETERMINATE_SWITCH_TIMEOUT_MS = 3000; 93f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 94f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 95f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu protected void onCreate(Bundle savedInstanceState) { 96f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu super.onCreate(savedInstanceState); 97f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu doBindHelperService(); 98f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 99f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setContentView(R.layout.ingest_activity_item_list); 100f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView = (IngestGridView) findViewById(R.id.ingest_gridview); 101f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mAdapter = new MtpAdapter(this); 102f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mAdapter.registerDataSetObserver(mMasterObserver); 103f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setAdapter(mAdapter); 104f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setMultiChoiceModeListener(mMultiChoiceModeListener); 105f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setOnItemClickListener(mOnItemClickListener); 106f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setOnClearChoicesListener(mPositionMappingCheckBroker); 107f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 108f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mFullscreenPager = (ViewPager) findViewById(R.id.ingest_view_pager); 109f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 110f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler = new ItemListHandler(this); 111f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 112f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu MtpBitmapFetch.configureForContext(this); 113f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 114f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 115f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private OnItemClickListener mOnItemClickListener = new OnItemClickListener() { 116d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 117f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onItemClick(AdapterView<?> adapterView, View itemView, int position, 118f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu long arg3) { 119f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mLastCheckedPosition = position; 120f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setItemChecked(position, !mGridView.getCheckedItemPositions().get(position)); 121d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 122f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu }; 123d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 124f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private MultiChoiceModeListener mMultiChoiceModeListener = new MultiChoiceModeListener() { 125f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private boolean mIgnoreItemCheckedStateChanges = false; 126d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 127f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void updateSelectedTitle(ActionMode mode) { 128f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu int count = mGridView.getCheckedItemCount(); 129f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mode.setTitle(getResources().getQuantityString( 130f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu R.plurals.ingest_number_of_items_selected, count, count)); 131c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 132c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 133c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 134f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onItemCheckedStateChanged(ActionMode mode, int position, long id, 135f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu boolean checked) { 136f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mIgnoreItemCheckedStateChanges) { 137f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return; 138f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 139f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mAdapter.itemAtPositionIsBucket(position)) { 140f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu SparseBooleanArray checkedItems = mGridView.getCheckedItemPositions(); 141f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mIgnoreItemCheckedStateChanges = true; 142f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setItemChecked(position, false); 143f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 144f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Takes advantage of the fact that SectionIndexer imposes the 145f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // need to clamp to the valid range 146f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu int nextSectionStart = mAdapter.getPositionForSection( 147f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mAdapter.getSectionForPosition(position) + 1); 148f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (nextSectionStart == position) { 149f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu nextSectionStart = mAdapter.getCount(); 150f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 151f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 152f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu boolean rangeValue = false; // Value we want to set all of the bucket items to 153f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 154f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Determine if all the items in the bucket are currently checked, so that we 155f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // can uncheck them, otherwise we will check all items in the bucket. 156f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu for (int i = position + 1; i < nextSectionStart; i++) { 157f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (!checkedItems.get(i)) { 158f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu rangeValue = true; 159f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu break; 160f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 161f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 162f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 163f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Set all items in the bucket to the desired state 164f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu for (int i = position + 1; i < nextSectionStart; i++) { 165f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (checkedItems.get(i) != rangeValue) { 166f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setItemChecked(i, rangeValue); 167f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 168f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 169f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 170f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mPositionMappingCheckBroker.onBulkCheckedChange(); 171f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mIgnoreItemCheckedStateChanges = false; 172f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else { 173f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mPositionMappingCheckBroker.onCheckedChange(position, checked); 174f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 175f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mLastCheckedPosition = position; 176f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu updateSelectedTitle(mode); 177c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 178c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 179d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 180f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 181f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return onOptionsItemSelected(item); 182d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 183d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 184d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 185f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public boolean onCreateActionMode(ActionMode mode, Menu menu) { 186f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu MenuInflater inflater = mode.getMenuInflater(); 187f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu inflater.inflate(R.menu.ingest_menu_item_list_selection, menu); 188f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu updateSelectedTitle(mode); 189f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActiveActionMode = mode; 190f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActionMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view); 191f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setSwitcherMenuState(mActionMenuSwitcherItem, mFullscreenPagerVisible); 192f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return true; 193d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 194d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 195d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 196f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onDestroyActionMode(ActionMode mode) { 197f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActiveActionMode = null; 198f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActionMenuSwitcherItem = null; 199f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_BULK_CHECKED_CHANGE); 200d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 201d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 202c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu @Override 203f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 204f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu updateSelectedTitle(mode); 205f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return false; 2066516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 207f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu }; 208f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 209f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 210f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public boolean onOptionsItemSelected(MenuItem item) { 211f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu int id = item.getItemId(); 212f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (id == R.id.ingest_import_items) { 213f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mActiveActionMode != null) { 214f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperService.importSelectedItems( 215f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.getCheckedItemPositions(), 216f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mAdapter); 217f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActiveActionMode.finish(); 218f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 219f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return true; 220f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else if (id == R.id.ingest_switch_view) { 221f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setFullscreenPagerVisibility(!mFullscreenPagerVisible); 222f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return true; 223f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else { 224f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return false; 2256516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 226f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 227f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 228f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 229f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public boolean onCreateOptionsMenu(Menu menu) { 230f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu MenuInflater inflater = getMenuInflater(); 231f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu inflater.inflate(R.menu.ingest_menu_item_list_selection, menu); 232f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view); 233f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu menu.findItem(R.id.ingest_import_items).setVisible(false); 234f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setSwitcherMenuState(mMenuSwitcherItem, mFullscreenPagerVisible); 235f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return true; 236f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 237f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 238f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 239f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu protected void onDestroy() { 240f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu doUnbindHelperService(); 241f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu super.onDestroy(); 242f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 243f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 244f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 245f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu protected void onResume() { 246f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu DateTileView.refreshLocale(); 247f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActive = true; 248f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mHelperService != null) { 249f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperService.setClientActivity(this); 250c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 251f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu updateWarningView(); 252f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu super.onResume(); 253f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 254f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 255f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 256f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu protected void onPause() { 257f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mHelperService != null) { 258f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperService.setClientActivity(null); 259c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 260f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActive = false; 261f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu cleanupProgressDialog(); 262f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu super.onPause(); 263f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 264f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 265f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 266f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onConfigurationChanged(Configuration newConfig) { 267f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu super.onConfigurationChanged(newConfig); 268f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu MtpBitmapFetch.configureForContext(this); 269f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 270f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 271f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void showWarningView(int textResId) { 272f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mWarningView == null) { 273f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mWarningView = findViewById(R.id.ingest_warning_view); 274f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mWarningText = 275f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu (TextView) mWarningView.findViewById(R.id.ingest_warning_view_text); 276c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 277f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mWarningText.setText(textResId); 278f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mWarningView.setVisibility(View.VISIBLE); 279f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setFullscreenPagerVisibility(false); 280f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setVisibility(View.GONE); 281f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setSwitcherMenuVisibility(false); 282f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 283f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 284f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void hideWarningView() { 285f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mWarningView != null) { 286f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mWarningView.setVisibility(View.GONE); 287f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setFullscreenPagerVisibility(false); 2886516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 289f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setSwitcherMenuVisibility(true); 290f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 291f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 292f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private PositionMappingCheckBroker mPositionMappingCheckBroker = 293f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu new PositionMappingCheckBroker(); 294f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 295f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private class PositionMappingCheckBroker extends CheckBroker 296f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu implements OnClearChoicesListener { 297f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private int mLastMappingPager = -1; 298f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private int mLastMappingGrid = -1; 299f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 300f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private int mapPagerToGridPosition(int position) { 301f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (position != mLastMappingPager) { 302f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mLastMappingPager = position; 303f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mLastMappingGrid = mAdapter.translatePositionWithoutLabels(position); 304f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 305f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return mLastMappingGrid; 3066516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu } 3076516d271e11f9ae9928be3bb70c99531a842c577Bobby Georgescu 308f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private int mapGridToPagerPosition(int position) { 309f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (position != mLastMappingGrid) { 310f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mLastMappingGrid = position; 311f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mLastMappingPager = mPagerAdapter.translatePositionWithLabels(position); 312f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 313f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return mLastMappingPager; 314d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 315d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 316f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 317f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void setItemChecked(int position, boolean checked) { 318f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setItemChecked(mapPagerToGridPosition(position), checked); 319d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 320d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 321d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 322f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onCheckedChange(int position, boolean checked) { 323f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mPagerAdapter != null) { 324f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu super.onCheckedChange(mapGridToPagerPosition(position), checked); 325f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 326d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 327d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 328d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 329f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public boolean isItemChecked(int position) { 330f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return mGridView.getCheckedItemPositions().get(mapPagerToGridPosition(position)); 331d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 332d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 333d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 334f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onClearChoices() { 335f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu onBulkCheckedChange(); 336d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 337f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 338d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 339f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private DataSetObserver mMasterObserver = new DataSetObserver() { 340d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 341f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onChanged() { 342f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mPagerAdapter != null) { 343f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mPagerAdapter.notifyDataSetChanged(); 344f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 345d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 346d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 347d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu @Override 348f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onInvalidated() { 349f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mPagerAdapter != null) { 350f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mPagerAdapter.notifyDataSetChanged(); 351f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 352f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 353f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu }; 354f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 355f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private int pickFullscreenStartingPosition() { 356f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu int firstVisiblePosition = mGridView.getFirstVisiblePosition(); 357f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mLastCheckedPosition <= firstVisiblePosition 358f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu || mLastCheckedPosition > mGridView.getLastVisiblePosition()) { 359f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return firstVisiblePosition; 360f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else { 361f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return mLastCheckedPosition; 362d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 363f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 364d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 365f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void setSwitcherMenuState(MenuItem menuItem, boolean inFullscreenMode) { 366f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (menuItem == null) { 367f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return; 368f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 369f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (!inFullscreenMode) { 370f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu menuItem.setIcon(android.R.drawable.ic_menu_zoom); 371f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu menuItem.setTitle(R.string.ingest_switch_photo_fullscreen); 372f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else { 373f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu menuItem.setIcon(android.R.drawable.ic_dialog_dialer); 374f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu menuItem.setTitle(R.string.ingest_switch_photo_grid); 375f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 376f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 377f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 378f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void setFullscreenPagerVisibility(boolean visible) { 379f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mFullscreenPagerVisible = visible; 380f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (visible) { 381f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mPagerAdapter == null) { 382f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mPagerAdapter = new MtpPagerAdapter(this, mPositionMappingCheckBroker); 383f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mPagerAdapter.setMtpDeviceIndex(mAdapter.getMtpDeviceIndex()); 384f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 385f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mFullscreenPager.setAdapter(mPagerAdapter); 386f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mFullscreenPager.setCurrentItem(mPagerAdapter.translatePositionWithLabels( 387f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu pickFullscreenStartingPosition()), false); 388f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else if (mPagerAdapter != null) { 389f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setSelection(mAdapter.translatePositionWithoutLabels( 390f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mFullscreenPager.getCurrentItem())); 391f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mFullscreenPager.setAdapter(null); 392f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 393f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mGridView.setVisibility(visible ? View.INVISIBLE : View.VISIBLE); 394f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mFullscreenPager.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 395f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mActionMenuSwitcherItem != null) { 396f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setSwitcherMenuState(mActionMenuSwitcherItem, visible); 397d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 398f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu setSwitcherMenuState(mMenuSwitcherItem, visible); 399f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 400d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 401f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void setSwitcherMenuVisibility(boolean visible) { 402f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mActionMenuSwitcherItem != null) { 403f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActionMenuSwitcherItem.setVisible(visible); 4040c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu } 405f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mMenuSwitcherItem != null) { 406f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mMenuSwitcherItem.setVisible(visible); 407f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 408f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 409f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 410f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void updateWarningView() { 411f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (!mAdapter.deviceConnected()) { 412f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu showWarningView(R.string.ingest_no_device); 413f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else if (mAdapter.indexReady() && mAdapter.getCount() == 0) { 414f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu showWarningView(R.string.ingest_empty_device); 415f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } else { 416f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu hideWarningView(); 417f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 418f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 4190c63c43455348ce01aff5f50f8b50b4612c0f8bfBobby Georgescu 420f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void uiThreadNotifyIndexChanged() { 421f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mAdapter.notifyDataSetChanged(); 422f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mActiveActionMode != null) { 423f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActiveActionMode.finish(); 424f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mActiveActionMode = null; 425f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 426f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu updateWarningView(); 427f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 428f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 429f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu protected void notifyIndexChanged() { 430f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED); 431f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 432f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 433f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private static class ProgressState { 434f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu String message; 435f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu String title; 436f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu int current; 437f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu int max; 438f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 439f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void reset() { 440f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu title = null; 441f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu message = null; 442f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu current = 0; 443f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu max = 0; 444f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 445f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 446f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 447f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private ProgressState mProgressState = new ProgressState(); 448f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 449f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 450f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onObjectIndexed(IngestObjectInfo object, int numVisited) { 451f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Not guaranteed to be called on the UI thread 452f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.reset(); 453f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.max = 0; 454f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.message = getResources().getQuantityString( 455f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu R.plurals.ingest_number_of_items_scanned, numVisited, numVisited); 456f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE); 457f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 458f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 459f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 460f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onSortingStarted() { 461f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Not guaranteed to be called on the UI thread 462f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.reset(); 463f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.max = 0; 464f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.message = getResources().getString(R.string.ingest_sorting); 465f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE); 466f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 467f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 468f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 469f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onIndexingFinished() { 470f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Not guaranteed to be called on the UI thread 471f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE); 472f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED); 473f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 474f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 475f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 476f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onImportProgress(final int visitedCount, final int totalCount, 477f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu String pathIfSuccessful) { 478f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Not guaranteed to be called on the UI thread 479f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.reset(); 480f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.max = totalCount; 481f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.current = visitedCount; 482f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressState.title = getResources().getString(R.string.ingest_importing); 483f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE); 484f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE); 485f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessageDelayed(ItemListHandler.MSG_PROGRESS_INDETERMINATE, 486f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu INDETERMINATE_SWITCH_TIMEOUT_MS); 487f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 488f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 489f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 490f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onImportFinish(Collection<IngestObjectInfo> objectsNotImported, 491f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu int numVisited) { 492f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // Not guaranteed to be called on the UI thread 493f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE); 494f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE); 495f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // TODO(georgescu): maybe show an extra dialog listing the ones that failed 496f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // importing, if any? 497f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 498f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 499f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private ProgressDialog getProgressDialog() { 500f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mProgressDialog == null || !mProgressDialog.isShowing()) { 501f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressDialog = new ProgressDialog(this); 502f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressDialog.setCancelable(false); 503f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 504f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return mProgressDialog; 505f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 506f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 507f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void updateProgressDialog() { 508f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu ProgressDialog dialog = getProgressDialog(); 509f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu boolean indeterminate = (mProgressState.max == 0); 510f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.setIndeterminate(indeterminate); 511f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.setProgressStyle(indeterminate ? ProgressDialog.STYLE_SPINNER 512f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu : ProgressDialog.STYLE_HORIZONTAL); 513f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mProgressState.title != null) { 514f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.setTitle(mProgressState.title); 515f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 516f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mProgressState.message != null) { 517f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.setMessage(mProgressState.message); 518f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 519f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (!indeterminate) { 520f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.setProgress(mProgressState.current); 521f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.setMax(mProgressState.max); 522f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 523f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (!dialog.isShowing()) { 524f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.show(); 525d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 526f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 527d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 528f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void makeProgressDialogIndeterminate() { 529f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu ProgressDialog dialog = getProgressDialog(); 530f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu dialog.setIndeterminate(true); 531f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 532d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 533f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void cleanupProgressDialog() { 534f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mProgressDialog != null) { 535f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressDialog.dismiss(); 536f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mProgressDialog = null; 537f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 538f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 539d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 540f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu // This is static and uses a WeakReference in order to avoid leaking the Activity 541f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private static class ItemListHandler extends Handler { 542f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public static final int MSG_PROGRESS_UPDATE = 0; 543f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public static final int MSG_PROGRESS_HIDE = 1; 544f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public static final int MSG_NOTIFY_CHANGED = 2; 545f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public static final int MSG_BULK_CHECKED_CHANGE = 3; 546f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public static final int MSG_PROGRESS_INDETERMINATE = 4; 547d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 548f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu WeakReference<IngestActivity> mParentReference; 549f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 550f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public ItemListHandler(IngestActivity parent) { 551f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu super(); 552f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mParentReference = new WeakReference<IngestActivity>(parent); 553d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 554d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 555f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 556f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void handleMessage(Message message) { 557f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu IngestActivity parent = mParentReference.get(); 558f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (parent == null || !parent.mActive) { 559f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu return; 560f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 561f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu switch (message.what) { 562f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu case MSG_PROGRESS_HIDE: 563f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu parent.cleanupProgressDialog(); 564f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu break; 565f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu case MSG_PROGRESS_UPDATE: 566f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu parent.updateProgressDialog(); 567f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu break; 568f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu case MSG_NOTIFY_CHANGED: 569f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu parent.uiThreadNotifyIndexChanged(); 570f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu break; 571f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu case MSG_BULK_CHECKED_CHANGE: 572f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu parent.mPositionMappingCheckBroker.onBulkCheckedChange(); 573f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu break; 574f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu case MSG_PROGRESS_INDETERMINATE: 575f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu parent.makeProgressDialogIndeterminate(); 576f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu break; 577f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu default: 578f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu break; 579f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 580f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 581f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 582d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 583f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private ServiceConnection mHelperServiceConnection = new ServiceConnection() { 584f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 585f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onServiceConnected(ComponentName className, IBinder service) { 586f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperService = ((IngestService.LocalBinder) service).getService(); 587f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperService.setClientActivity(IngestActivity.this); 588f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu MtpDeviceIndex index = mHelperService.getIndex(); 589f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mAdapter.setMtpDeviceIndex(index); 590f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mPagerAdapter != null) { 591f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mPagerAdapter.setMtpDeviceIndex(index); 592f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 593f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 594d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 595f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu @Override 596f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu public void onServiceDisconnected(ComponentName className) { 597f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperService = null; 598d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 599f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu }; 600d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu 601f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void doBindHelperService() { 602f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu bindService(new Intent(getApplicationContext(), IngestService.class), 603f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperServiceConnection, Context.BIND_AUTO_CREATE); 604f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 605f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu 606f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu private void doUnbindHelperService() { 607f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu if (mHelperService != null) { 608f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu mHelperService.setClientActivity(null); 609f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu unbindService(mHelperServiceConnection); 610d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu } 611f640d379259bb114a50e3200f49961b89d60f2c2Bobby Georgescu } 612d3aac52ffb88ced53413d5eef29c641dd6982267Bobby Georgescu} 613