1785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung/* 2785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Copyright (C) 2011 The Android Open Source Project 3785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * 4785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * you may not use this file except in compliance with the License. 6785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * You may obtain a copy of the License at 7785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * 8785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * 10785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Unless required by applicable law or agreed to in writing, software 11785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * See the License for the specific language governing permissions and 14785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * limitations under the License. 15785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */ 16785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 17785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungpackage com.android.launcher2; 18785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 1955b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chungimport android.animation.AnimatorSet; 20d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chungimport android.animation.ValueAnimator; 21ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohenimport android.appwidget.AppWidgetHostView; 22785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.appwidget.AppWidgetManager; 23785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.appwidget.AppWidgetProviderInfo; 24785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.ComponentName; 25785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.Context; 26785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.Intent; 27374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasaniimport android.content.pm.LauncherActivityInfo; 28374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasaniimport android.content.pm.LauncherApps; 29785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.pm.PackageManager; 30785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.pm.ResolveInfo; 31f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chungimport android.content.res.Configuration; 32785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.res.Resources; 33785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.res.TypedArray; 34785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.graphics.Bitmap; 35785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.graphics.Canvas; 3605713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurkaimport android.graphics.Point; 37785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.graphics.Rect; 38785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.graphics.drawable.Drawable; 39b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungimport android.os.AsyncTask; 409e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohenimport android.os.Build; 419e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohenimport android.os.Bundle; 42b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungimport android.os.Process; 43785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.util.AttributeSet; 44785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.util.Log; 45374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasaniimport android.util.SparseArray; 4672d8b393b03f9decba05b0797608ccdc751fecefWinson Chungimport android.view.Gravity; 47c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chungimport android.view.KeyEvent; 48785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.LayoutInflater; 49785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.View; 5063257c110a4ee54d5e8872c471cce254cf613c7aWinson Chungimport android.view.ViewGroup; 5155b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chungimport android.view.animation.AccelerateInterpolator; 522591f6a5202664faf8cde2b68361e3842ce76ba9Adam Cohenimport android.view.animation.DecelerateInterpolator; 53fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chungimport android.widget.GridLayout; 54785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.widget.ImageView; 5555b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chungimport android.widget.Toast; 56785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 57785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport com.android.launcher.R; 58c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport com.android.launcher2.DropTarget.DragObject; 59c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 60c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList; 61c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.Collections; 62c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.Iterator; 63c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.List; 64785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 65b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung/** 66b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * A simple callback interface which also provides the results of the task. 67b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung */ 68b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chunginterface AsyncTaskCallback { 69b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data); 70b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung} 714e076545e4ccdbd3c045a3fa33869a2b7519a0ccWinson Chung 72b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung/** 73b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * The data needed to perform either of the custom AsyncTasks. 74b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung */ 75b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungclass AsyncTaskPageData { 76875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung enum Type { 7782369a16126a1030c1c9203dc62b33c2598add89Michael Jurka LoadWidgetPreviewData 78875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung } 79875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung 80038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka AsyncTaskPageData(int p, ArrayList<Object> l, int cw, int ch, AsyncTaskCallback bgR, 813f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka AsyncTaskCallback postR, WidgetPreviewLoader w) { 82b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung page = p; 83b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung items = l; 844e076545e4ccdbd3c045a3fa33869a2b7519a0ccWinson Chung generatedImages = new ArrayList<Bitmap>(); 85038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka maxImageWidth = cw; 86038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka maxImageHeight = ch; 87b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung doInBackgroundCallback = bgR; 88b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung postExecuteCallback = postR; 893f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka widgetPreviewLoader = w; 90b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 91099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung void cleanup(boolean cancelled) { 92099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung // Clean up any references to source/generated bitmaps 93099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung if (generatedImages != null) { 94099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung if (cancelled) { 9505713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka for (int i = 0; i < generatedImages.size(); i++) { 96ee8e99fe3bde78885904b4d9ea789b4d2a6f2b16Michael Jurka widgetPreviewLoader.recycleBitmap(items.get(i), generatedImages.get(i)); 97099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } 98099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } 99099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung generatedImages.clear(); 100099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } 101099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } 102b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung int page; 103b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung ArrayList<Object> items; 1044e076545e4ccdbd3c045a3fa33869a2b7519a0ccWinson Chung ArrayList<Bitmap> sourceImages; 1054e076545e4ccdbd3c045a3fa33869a2b7519a0ccWinson Chung ArrayList<Bitmap> generatedImages; 106038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka int maxImageWidth; 107038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka int maxImageHeight; 108b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung AsyncTaskCallback doInBackgroundCallback; 109b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung AsyncTaskCallback postExecuteCallback; 1103f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka WidgetPreviewLoader widgetPreviewLoader; 111b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung} 1124e076545e4ccdbd3c045a3fa33869a2b7519a0ccWinson Chung 113b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung/** 114b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * A generic template for an async task used in AppsCustomize. 115b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung */ 116b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungclass AppsCustomizeAsyncTask extends AsyncTask<AsyncTaskPageData, Void, AsyncTaskPageData> { 1170cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen AppsCustomizeAsyncTask(int p, AsyncTaskPageData.Type ty) { 118b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung page = p; 119b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung threadPriority = Process.THREAD_PRIORITY_DEFAULT; 120875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung dataType = ty; 121b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 122b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung @Override 123b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung protected AsyncTaskPageData doInBackground(AsyncTaskPageData... params) { 124b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung if (params.length != 1) return null; 125b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung // Load each of the widget previews in the background 126b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung params[0].doInBackgroundCallback.run(this, params[0]); 127b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung return params[0]; 128b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 129b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung @Override 130b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung protected void onPostExecute(AsyncTaskPageData result) { 131b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung // All the widget previews are loaded, so we can just callback to inflate the page 132b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung result.postExecuteCallback.run(this, result); 133b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 134b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 135b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung void setThreadPriority(int p) { 136b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung threadPriority = p; 137b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 138b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung void syncThreadPriority() { 139b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung Process.setThreadPriority(threadPriority); 140b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 141b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 142b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung // The page that this async task is associated with 143875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung AsyncTaskPageData.Type dataType; 144b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung int page; 145b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung int threadPriority; 146b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung} 147b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 148b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung/** 149b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * The Apps/Customize page that displays all the applications, widgets, and shortcuts. 150b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung */ 151785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungpublic class AppsCustomizePagedView extends PagedViewWithDraggableItems implements 152cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung View.OnClickListener, View.OnKeyListener, DragSource, 15339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener, 15439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka LauncherTransitionable { 1550e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen static final String TAG = "AppsCustomizePagedView"; 156785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 157785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung /** 158785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * The different content types that this paged view can show. 159785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */ 160785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public enum ContentType { 161785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung Applications, 1626a26e5bed48bf64996aef3ea1db4767ee147640eWinson Chung Widgets 163785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 164785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 165785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // Refs 166785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private Launcher mLauncher; 167785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private DragController mDragController; 168785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private final LayoutInflater mLayoutInflater; 169785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private final PackageManager mPackageManager; 170785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 1715afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung // Save and Restore 1725afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung private int mSaveInstanceStateItemIndex = -1; 173e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung private PagedViewIcon mPressedIcon; 1745afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung 175785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // Content 176785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private ArrayList<ApplicationInfo> mApps; 177d294526ad99db70d882a1e11f2b0f878524163faWinson Chung private ArrayList<Object> mWidgets; 1781ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung 1797d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung // Cling 1803f4e1423804d64a38cb69e4511d7b80783564827Winson Chung private boolean mHasShownAllAppsCling; 1817d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung private int mClingFocusedX; 1827d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung private int mClingFocusedY; 1837d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung 1841ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung // Caching 185b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung private Canvas mCanvas; 1864dbea7920a5f52df1d35009352f7e5cba16c05fbWinson Chung private IconCache mIconCache; 187785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 188785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // Dimens 189785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private int mContentWidth; 1906032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung private int mMaxAppCellCountX, mMaxAppCellCountY; 1914b576be59e58072cc03b5a8d36afb6a322513575Winson Chung private int mWidgetCountX, mWidgetCountY; 192d294526ad99db70d882a1e11f2b0f878524163faWinson Chung private int mWidgetWidthGap, mWidgetHeightGap; 193785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private PagedViewCellLayout mWidgetSpacingLayout; 1940cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen private int mNumAppsPages; 1950cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen private int mNumWidgetPages; 196785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 19722f823d340710bcde587b18a1542570cbe0360f5Adam Cohen // Relating to the scroll and overscroll effects 19822f823d340710bcde587b18a1542570cbe0360f5Adam Cohen Workspace.ZInterpolator mZInterpolator = new Workspace.ZInterpolator(0.5f); 199cff6af81d721415785bddc2efd74e179d2def9daAdam Cohen private static float CAMERA_DISTANCE = 6500; 200b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen private static float TRANSITION_SCALE_FACTOR = 0.74f; 201cff6af81d721415785bddc2efd74e179d2def9daAdam Cohen private static float TRANSITION_PIVOT = 0.65f; 202cff6af81d721415785bddc2efd74e179d2def9daAdam Cohen private static float TRANSITION_MAX_ROTATION = 22; 203cff6af81d721415785bddc2efd74e179d2def9daAdam Cohen private static final boolean PERFORM_OVERSCROLL_ROTATION = true; 204b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen private AccelerateInterpolator mAlphaInterpolator = new AccelerateInterpolator(0.9f); 2052591f6a5202664faf8cde2b68361e3842ce76ba9Adam Cohen private DecelerateInterpolator mLeftScreenAlphaInterpolator = new DecelerateInterpolator(4); 20622f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 207b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung // Previews & outlines 208b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung ArrayList<AppsCustomizeAsyncTask> mRunningTasks; 20968e4c64a67f4a40afac4cab44def461783f096a4Winson Chung private static final int sPageSleepDelay = 200; 2104b576be59e58072cc03b5a8d36afb6a322513575Winson Chung 211ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen private Runnable mInflateWidgetRunnable = null; 212ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen private Runnable mBindWidgetRunnable = null; 213ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen static final int WIDGET_NO_CLEANUP_REQUIRED = -1; 21421a170b2e17621583f2800d5611459a0a939f560Adam Cohen static final int WIDGET_PRELOAD_PENDING = 0; 21521a170b2e17621583f2800d5611459a0a939f560Adam Cohen static final int WIDGET_BOUND = 1; 21621a170b2e17621583f2800d5611459a0a939f560Adam Cohen static final int WIDGET_INFLATED = 2; 217ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED; 218ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int mWidgetLoadingId = -1; 2191b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen PendingAddWidgetInfo mCreateWidgetInfo = null; 2207a326648c54922c60c32088e173c93068a82d107Adam Cohen private boolean mDraggingWidget = false; 221ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 222cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung private Toast mWidgetInstructionToast; 223cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung 22439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka // Deferral of loading widget previews during launcher transitions 22539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka private boolean mInTransition; 22639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka private ArrayList<AsyncTaskPageData> mDeferredSyncWidgetPageItems = 22739e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka new ArrayList<AsyncTaskPageData>(); 228f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka private ArrayList<Runnable> mDeferredPrepareLoadWidgetPreviewsTasks = 229f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka new ArrayList<Runnable>(); 23039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka 2319e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen private Rect mTmpRect = new Rect(); 2329e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen 233dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka // Used for drawing shortcut previews 234dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka BitmapCache mCachedShortcutPreviewBitmap = new BitmapCache(); 235dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka PaintCache mCachedShortcutPreviewPaint = new PaintCache(); 236dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka CanvasCache mCachedShortcutPreviewCanvas = new CanvasCache(); 237dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka 238dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka // Used for drawing widget previews 239dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka CanvasCache mCachedAppWidgetPreviewCanvas = new CanvasCache(); 240dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka RectCache mCachedAppWidgetPreviewSrcRect = new RectCache(); 241dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka RectCache mCachedAppWidgetPreviewDestRect = new RectCache(); 242dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka PaintCache mCachedAppWidgetPreviewPaint = new PaintCache(); 243dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka 24405713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka WidgetPreviewLoader mWidgetPreviewLoader; 24505713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka 246c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka private boolean mInBulkBind; 247c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka private boolean mNeedToUpdatePageCountsAndInvalidateData; 248c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka 249785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public AppsCustomizePagedView(Context context, AttributeSet attrs) { 250785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung super(context, attrs); 251785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mLayoutInflater = LayoutInflater.from(context); 252785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mPackageManager = context.getPackageManager(); 253785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mApps = new ArrayList<ApplicationInfo>(); 2541ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung mWidgets = new ArrayList<Object>(); 2554dbea7920a5f52df1d35009352f7e5cba16c05fbWinson Chung mIconCache = ((LauncherApplication) context.getApplicationContext()).getIconCache(); 256b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung mCanvas = new Canvas(); 257b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung mRunningTasks = new ArrayList<AppsCustomizeAsyncTask>(); 2581ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung 2591ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung // Save the default widget preview background 2606032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0); 2616032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung mMaxAppCellCountX = a.getInt(R.styleable.AppsCustomizePagedView_maxAppCellCountX, -1); 2626032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung mMaxAppCellCountY = a.getInt(R.styleable.AppsCustomizePagedView_maxAppCellCountY, -1); 263f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mWidgetWidthGap = 264f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellWidthGap, 0); 265f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mWidgetHeightGap = 266f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellHeightGap, 0); 2674b576be59e58072cc03b5a8d36afb6a322513575Winson Chung mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2); 2684b576be59e58072cc03b5a8d36afb6a322513575Winson Chung mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2); 2697d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung mClingFocusedX = a.getInt(R.styleable.AppsCustomizePagedView_clingFocusedX, 0); 2707d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung mClingFocusedY = a.getInt(R.styleable.AppsCustomizePagedView_clingFocusedY, 0); 2714b576be59e58072cc03b5a8d36afb6a322513575Winson Chung a.recycle(); 272f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mWidgetSpacingLayout = new PagedViewCellLayout(getContext()); 2734b576be59e58072cc03b5a8d36afb6a322513575Winson Chung 2741ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung // The padding on the non-matched dimension for the default widget preview icons 2751ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung // (top + bottom) 2762591f6a5202664faf8cde2b68361e3842ce76ba9Adam Cohen mFadeInAdjacentScreens = false; 27708055f66528330ff1a1d1d13c856647d86dd967dSvetoslav Ganov 27808055f66528330ff1a1d1d13c856647d86dd967dSvetoslav Ganov // Unless otherwise specified this view is important for accessibility. 27908055f66528330ff1a1d1d13c856647d86dd967dSvetoslav Ganov if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { 28008055f66528330ff1a1d1d13c856647d86dd967dSvetoslav Ganov setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); 28108055f66528330ff1a1d1d13c856647d86dd967dSvetoslav Ganov } 282785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 283785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 284785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung @Override 285785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung protected void init() { 286785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung super.init(); 2876a877403542c71c1b6228c429bc060755f5f847bWinson Chung mCenterPagesVertically = false; 288785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 289785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung Context context = getContext(); 290785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung Resources r = context.getResources(); 291785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f); 292785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 293785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 2945afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung /** Returns the item index of the center item on this page so that we can restore to this 2955afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung * item index when we rotate. */ 2965afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung private int getMiddleComponentIndexOnCurrentPage() { 2975afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int i = -1; 2985afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung if (getPageCount() > 0) { 2995afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int currentPage = getCurrentPage(); 3000cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen if (currentPage < mNumAppsPages) { 30122f823d340710bcde587b18a1542570cbe0360f5Adam Cohen PagedViewCellLayout layout = (PagedViewCellLayout) getPageAt(currentPage); 3025afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung PagedViewCellLayoutChildren childrenLayout = layout.getChildrenLayout(); 3035afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int numItemsPerPage = mCellCountX * mCellCountY; 3045afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int childCount = childrenLayout.getChildCount(); 3055afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung if (childCount > 0) { 3065afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung i = (currentPage * numItemsPerPage) + (childCount / 2); 3070cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 3080cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } else { 3090cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen int numApps = mApps.size(); 31022f823d340710bcde587b18a1542570cbe0360f5Adam Cohen PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(currentPage); 3115afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int numItemsPerPage = mWidgetCountX * mWidgetCountY; 3125afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int childCount = layout.getChildCount(); 3135afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung if (childCount > 0) { 3140cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen i = numApps + 3150cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen ((currentPage - mNumAppsPages) * numItemsPerPage) + (childCount / 2); 3160cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 3175afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 3185afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 3195afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung return i; 3205afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 3215afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung 3225afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung /** Get the index of the item to restore to if we need to restore the current page. */ 3235afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int getSaveInstanceStateIndex() { 3245afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung if (mSaveInstanceStateItemIndex == -1) { 3255afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung mSaveInstanceStateItemIndex = getMiddleComponentIndexOnCurrentPage(); 3265afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 3275afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung return mSaveInstanceStateItemIndex; 3285afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 3295afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung 3305afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung /** Returns the page in the current orientation which is expected to contain the specified 3315afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung * item index. */ 3325afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int getPageForComponent(int index) { 3330cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen if (index < 0) return 0; 3340cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 3350cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen if (index < mApps.size()) { 3365afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int numItemsPerPage = mCellCountX * mCellCountY; 3375afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung return (index / numItemsPerPage); 3380cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } else { 3395afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung int numItemsPerPage = mWidgetCountX * mWidgetCountY; 3400cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen return mNumAppsPages + ((index - mApps.size()) / numItemsPerPage); 3410cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 3425afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 3435afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung 3445afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung /** Restores the page for an item at the specified index */ 3455afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung void restorePageForIndex(int index) { 3465afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung if (index < 0) return; 3470cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen mSaveInstanceStateItemIndex = index; 3485afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung } 3495afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung 3504b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung private void updatePageCounts() { 3514b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung mNumWidgetPages = (int) Math.ceil(mWidgets.size() / 3524b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung (float) (mWidgetCountX * mWidgetCountY)); 3534b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung mNumAppsPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY)); 3544b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung } 3554b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung 356f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung protected void onDataReady(int width, int height) { 3573f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka if (mWidgetPreviewLoader == null) { 3583f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka mWidgetPreviewLoader = new WidgetPreviewLoader(mLauncher); 3593f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka } 3603f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka 361f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // Note that we transpose the counts in portrait so that we get a similar layout 362f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung boolean isLandscape = getResources().getConfiguration().orientation == 363f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung Configuration.ORIENTATION_LANDSCAPE; 364f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int maxCellCountX = Integer.MAX_VALUE; 365f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int maxCellCountY = Integer.MAX_VALUE; 366f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung if (LauncherApplication.isScreenLarge()) { 367f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung maxCellCountX = (isLandscape ? LauncherModel.getCellCountX() : 368f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung LauncherModel.getCellCountY()); 369f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung maxCellCountY = (isLandscape ? LauncherModel.getCellCountY() : 370f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung LauncherModel.getCellCountX()); 371f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 3726032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung if (mMaxAppCellCountX > -1) { 3736032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung maxCellCountX = Math.min(maxCellCountX, mMaxAppCellCountX); 3746032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung } 375244ebcd7b41fea9edbbbd12525973b1c6d6bcfe1Michael Jurka // Temp hack for now: only use the max cell count Y for widget layout 376244ebcd7b41fea9edbbbd12525973b1c6d6bcfe1Michael Jurka int maxWidgetCellCountY = maxCellCountY; 3776032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung if (mMaxAppCellCountY > -1) { 378244ebcd7b41fea9edbbbd12525973b1c6d6bcfe1Michael Jurka maxWidgetCellCountY = Math.min(maxWidgetCellCountY, mMaxAppCellCountY); 3796032e7ed8e6208348a6b3f8bc1a7ecafc7951af8Winson Chung } 380f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 381f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // Now that the data is ready, we can calculate the content width, the number of cells to 382f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // use for each page 383f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mWidgetSpacingLayout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap); 384f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mWidgetSpacingLayout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, 385f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mPageLayoutPaddingRight, mPageLayoutPaddingBottom); 386f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mWidgetSpacingLayout.calculateCellCount(width, height, maxCellCountX, maxCellCountY); 387f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mCellCountX = mWidgetSpacingLayout.getCellCountX(); 388f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mCellCountY = mWidgetSpacingLayout.getCellCountY(); 3894b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung updatePageCounts(); 3905a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung 391db1138b4efae89a3b5833547958a3606e5408a71Winson Chung // Force a measure to update recalculate the gaps 392db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST); 393db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST); 394244ebcd7b41fea9edbbbd12525973b1c6d6bcfe1Michael Jurka mWidgetSpacingLayout.calculateCellCount(width, height, maxCellCountX, maxWidgetCellCountY); 395db1138b4efae89a3b5833547958a3606e5408a71Winson Chung mWidgetSpacingLayout.measure(widthSpec, heightSpec); 396f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung mContentWidth = mWidgetSpacingLayout.getContentWidth(); 3970cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 398e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka AppsCustomizeTabHost host = (AppsCustomizeTabHost) getTabHost(); 399e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka final boolean hostIsTransitioning = host.isTransitioning(); 400e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka 4010cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen // Restore the page 4020cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen int page = getPageForComponent(mSaveInstanceStateItemIndex); 403e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka invalidatePageData(Math.max(0, page), hostIsTransitioning); 4047d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung 4053f4e1423804d64a38cb69e4511d7b80783564827Winson Chung // Show All Apps cling if we are finished transitioning, otherwise, we will try again when 4063f4e1423804d64a38cb69e4511d7b80783564827Winson Chung // the transition completes in AppsCustomizeTabHost (otherwise the wrong offsets will be 4073f4e1423804d64a38cb69e4511d7b80783564827Winson Chung // returned while animating) 408e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka if (!hostIsTransitioning) { 4093f4e1423804d64a38cb69e4511d7b80783564827Winson Chung post(new Runnable() { 4103f4e1423804d64a38cb69e4511d7b80783564827Winson Chung @Override 4113f4e1423804d64a38cb69e4511d7b80783564827Winson Chung public void run() { 4123f4e1423804d64a38cb69e4511d7b80783564827Winson Chung showAllAppsCling(); 4133f4e1423804d64a38cb69e4511d7b80783564827Winson Chung } 4143f4e1423804d64a38cb69e4511d7b80783564827Winson Chung }); 4153f4e1423804d64a38cb69e4511d7b80783564827Winson Chung } 4163f4e1423804d64a38cb69e4511d7b80783564827Winson Chung } 4177d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung 4183f4e1423804d64a38cb69e4511d7b80783564827Winson Chung void showAllAppsCling() { 4199802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung if (!mHasShownAllAppsCling && isDataReady()) { 4203f4e1423804d64a38cb69e4511d7b80783564827Winson Chung mHasShownAllAppsCling = true; 4213f4e1423804d64a38cb69e4511d7b80783564827Winson Chung // Calculate the position for the cling punch through 4223f4e1423804d64a38cb69e4511d7b80783564827Winson Chung int[] offset = new int[2]; 4233f4e1423804d64a38cb69e4511d7b80783564827Winson Chung int[] pos = mWidgetSpacingLayout.estimateCellPosition(mClingFocusedX, mClingFocusedY); 4243f4e1423804d64a38cb69e4511d7b80783564827Winson Chung mLauncher.getDragLayer().getLocationInDragLayer(this, offset); 4253f4e1423804d64a38cb69e4511d7b80783564827Winson Chung // PagedViews are centered horizontally but top aligned 4267819abd2d191a170cbc9d4bd190001c465187a9dWinson Chung // Note we have to shift the items up now that Launcher sits under the status bar 4273f4e1423804d64a38cb69e4511d7b80783564827Winson Chung pos[0] += (getMeasuredWidth() - mWidgetSpacingLayout.getMeasuredWidth()) / 2 + 4283f4e1423804d64a38cb69e4511d7b80783564827Winson Chung offset[0]; 4297819abd2d191a170cbc9d4bd190001c465187a9dWinson Chung pos[1] += offset[1] - mLauncher.getDragLayer().getPaddingTop(); 4303f4e1423804d64a38cb69e4511d7b80783564827Winson Chung mLauncher.showFirstRunAllAppsCling(pos); 4313f4e1423804d64a38cb69e4511d7b80783564827Winson Chung } 432f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 433f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 434f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung @Override 435f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 436f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int width = MeasureSpec.getSize(widthMeasureSpec); 437f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int height = MeasureSpec.getSize(heightMeasureSpec); 438f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung if (!isDataReady()) { 439374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani if (mApps.size() > 0 && !mWidgets.isEmpty()) { 440f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung setDataIsReady(); 441f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung setMeasuredDimension(width, height); 442f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung onDataReady(width, height); 443f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 444f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 445f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 446f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung super.onMeasure(widthMeasureSpec, heightMeasureSpec); 447f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 448f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 449c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka public void onPackagesUpdated(ArrayList<Object> widgetsAndShortcuts) { 4501ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung // Get the list of widgets and shortcuts 4511ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung mWidgets.clear(); 452c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka for (Object o : widgetsAndShortcuts) { 453c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka if (o instanceof AppWidgetProviderInfo) { 454c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka AppWidgetProviderInfo widget = (AppWidgetProviderInfo) o; 455c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka if (widget.minWidth > 0 && widget.minHeight > 0) { 456c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka // Ensure that all widgets we show can be added on a workspace of this size 457c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget); 458c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget); 459c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka int minSpanX = Math.min(spanXY[0], minSpanXY[0]); 460c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka int minSpanY = Math.min(spanXY[1], minSpanXY[1]); 461c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka if (minSpanX <= LauncherModel.getCellCountX() && 462336d491492ae15cc97aebb2f9b263c8ec3718dcbAdam Cohen minSpanY <= LauncherModel.getCellCountY()) { 463c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka mWidgets.add(widget); 464c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } else { 465c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" + 466c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka widget.minWidth + ", " + widget.minHeight + ")"); 467c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 468fd39d8ee9512d873aaaa205839ca233c2be4d9d3Winson Chung } else { 469c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" + 470c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka widget.minWidth + ", " + widget.minHeight + ")"); 471a5c9636f563a2fa5bd3c97266894e002453b13dcWinson Chung } 472dbc1f657863dd9c57a2d30381d3fb36bc7076456Michael Jurka } else { 473c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka // just add shortcuts 474c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka mWidgets.add(o); 475c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 476c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 477c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka updatePageCountsAndInvalidateData(); 478c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 479c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka 480c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka public void setBulkBind(boolean bulkBind) { 481c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka if (bulkBind) { 482c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka mInBulkBind = true; 483c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } else { 484c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka mInBulkBind = false; 485c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka if (mNeedToUpdatePageCountsAndInvalidateData) { 486c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka updatePageCountsAndInvalidateData(); 487dbc1f657863dd9c57a2d30381d3fb36bc7076456Michael Jurka } 488dbc1f657863dd9c57a2d30381d3fb36bc7076456Michael Jurka } 489c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 490c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka 491c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka private void updatePageCountsAndInvalidateData() { 492c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka if (mInBulkBind) { 493c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka mNeedToUpdatePageCountsAndInvalidateData = true; 494c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } else { 495c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka updatePageCounts(); 496c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka invalidateOnDataChange(); 497c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka mNeedToUpdatePageCountsAndInvalidateData = false; 498c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 4994b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } 5004b576be59e58072cc03b5a8d36afb6a322513575Winson Chung 5014b576be59e58072cc03b5a8d36afb6a322513575Winson Chung @Override 5024b576be59e58072cc03b5a8d36afb6a322513575Winson Chung public void onClick(View v) { 503fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen // When we have exited all apps or are in transition, disregard clicks 504c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung if (!mLauncher.isAllAppsVisible() || 505fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mLauncher.getWorkspace().isSwitchingState()) return; 506fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 5074b576be59e58072cc03b5a8d36afb6a322513575Winson Chung if (v instanceof PagedViewIcon) { 5084b576be59e58072cc03b5a8d36afb6a322513575Winson Chung // Animate some feedback to the click 5094b576be59e58072cc03b5a8d36afb6a322513575Winson Chung final ApplicationInfo appInfo = (ApplicationInfo) v.getTag(); 5103b187b88baf80e520f6bd32d60abe6460d28a040Winson Chung 5113b187b88baf80e520f6bd32d60abe6460d28a040Winson Chung // Lock the drawable state to pressed until we return to Launcher 5123b187b88baf80e520f6bd32d60abe6460d28a040Winson Chung if (mPressedIcon != null) { 5133b187b88baf80e520f6bd32d60abe6460d28a040Winson Chung mPressedIcon.lockDrawableState(); 5143b187b88baf80e520f6bd32d60abe6460d28a040Winson Chung } 515c7450e3ebd7672fcd7b9d51a8c1e68f63c5ce86bWinson Chung 51618f41f8327860d7e257d063888d08b6b5c528fe9Winson Chung // NOTE: We want all transitions from launcher to act as if the wallpaper were enabled 51718f41f8327860d7e257d063888d08b6b5c528fe9Winson Chung // to be consistent. So re-enable the flag here, and we will re-disable it as necessary 51818f41f8327860d7e257d063888d08b6b5c528fe9Winson Chung // when Launcher resumes and we are still in AllApps. 51918f41f8327860d7e257d063888d08b6b5c528fe9Winson Chung mLauncher.updateWallpaperVisibility(true); 520c7450e3ebd7672fcd7b9d51a8c1e68f63c5ce86bWinson Chung mLauncher.startActivitySafely(v, appInfo.intent, appInfo); 521c7450e3ebd7672fcd7b9d51a8c1e68f63c5ce86bWinson Chung 5224b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } else if (v instanceof PagedViewWidget) { 523d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung // Let the user know that they have to long press to add a widget 524cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung if (mWidgetInstructionToast != null) { 525cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung mWidgetInstructionToast.cancel(); 526cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung } 527cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung mWidgetInstructionToast = Toast.makeText(getContext(),R.string.long_press_widget_to_add, 528cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung Toast.LENGTH_SHORT); 529cb9ab4f3aa04ad60355d119dfedca3052378d8f9Winson Chung mWidgetInstructionToast.show(); 530d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung 531d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung // Create a little animation to show that the widget can move 532d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung float offsetY = getResources().getDimensionPixelSize(R.dimen.dragViewOffsetY); 533d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung final ImageView p = (ImageView) v.findViewById(R.id.widget_preview); 5342ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka AnimatorSet bounce = LauncherAnimUtils.createAnimatorSet(); 5352ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka ValueAnimator tyuAnim = LauncherAnimUtils.ofFloat(p, "translationY", offsetY); 536d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung tyuAnim.setDuration(125); 5372ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka ValueAnimator tydAnim = LauncherAnimUtils.ofFloat(p, "translationY", 0f); 538d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung tydAnim.setDuration(100); 539d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung bounce.play(tyuAnim).before(tydAnim); 540d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung bounce.setInterpolator(new AccelerateInterpolator()); 541d2e87b32dc8c09590dd1ae186e97d3260955a568Winson Chung bounce.start(); 5424b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } 543785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 544785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 545c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung public boolean onKey(View v, int keyCode, KeyEvent event) { 546c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung return FocusHelper.handleAppsCustomizeKeyEvent(v, keyCode, event); 547c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung } 548c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung 549785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung /* 550785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * PagedViewWithDraggableItems implementation 551785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */ 552785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung @Override 553785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung protected void determineDraggingStart(android.view.MotionEvent ev) { 554785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // Disable dragging by pulling an app down for now. 555785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 556785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 557ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen private void beginDraggingApplication(View v) { 558ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen mLauncher.getWorkspace().onDragStartedWithItem(v); 559ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen mLauncher.getWorkspace().beginDragShared(v, this); 5604b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } 561ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 5629e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen Bundle getDefaultOptionsForWidget(Launcher launcher, PendingAddWidgetInfo info) { 5639e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen Bundle options = null; 5649e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 5659e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen AppWidgetResizeFrame.getWidgetSizeRanges(mLauncher, info.spanX, info.spanY, mTmpRect); 566aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(mLauncher, 567aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen info.componentName, null); 568aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen 569aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen float density = getResources().getDisplayMetrics().density; 570aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen int xPaddingDips = (int) ((padding.left + padding.right) / density); 571aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen int yPaddingDips = (int) ((padding.top + padding.bottom) / density); 572aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen 5739e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen options = new Bundle(); 574aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, 575aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen mTmpRect.left - xPaddingDips); 576aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, 577aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen mTmpRect.top - yPaddingDips); 578aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, 579aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen mTmpRect.right - xPaddingDips); 580aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, 581aaa5c21ee2e03def644fb6ba8eadbb59873ddd45Adam Cohen mTmpRect.bottom - yPaddingDips); 5829e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen } 5839e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen return options; 5849e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen } 5859e05a5ea951b4d5ffce324da8dd0656353306e6fAdam Cohen 586f1dcdf61132a6321d0c1c0eb670c6cf1493ab981Adam Cohen private void preloadWidget(final PendingAddWidgetInfo info) { 587ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen final AppWidgetProviderInfo pInfo = info.info; 588dd70d66852bb8bd16f55796e546ba290360d1198Adam Cohen final Bundle options = getDefaultOptionsForWidget(mLauncher, info); 589dd70d66852bb8bd16f55796e546ba290360d1198Adam Cohen 590ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen if (pInfo.configure != null) { 591dd70d66852bb8bd16f55796e546ba290360d1198Adam Cohen info.bindOptions = options; 592ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen return; 593ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 594ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 59521a170b2e17621583f2800d5611459a0a939f560Adam Cohen mWidgetCleanupState = WIDGET_PRELOAD_PENDING; 596ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mBindWidgetRunnable = new Runnable() { 597ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 598ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void run() { 599ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId(); 600610ded21c79ae3da4c105c2d1921a30732468a69Svet Ganov if (AppWidgetManager.getInstance(mLauncher).bindAppWidgetIdIfAllowed( 601610ded21c79ae3da4c105c2d1921a30732468a69Svet Ganov mWidgetLoadingId, info.info.getProfile(), info.componentName, options)) { 602610ded21c79ae3da4c105c2d1921a30732468a69Svet Ganov mWidgetCleanupState = WIDGET_BOUND; 6038b805b17158886035b38261eb611d8641701ae43Michael Jurka } 604ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 605ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen }; 606ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen post(mBindWidgetRunnable); 607ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 608ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mInflateWidgetRunnable = new Runnable() { 609ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 610ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void run() { 6111637d6d64ac85d75b69b90fd976ed449046ccdc6Michael Jurka if (mWidgetCleanupState != WIDGET_BOUND) { 6121637d6d64ac85d75b69b90fd976ed449046ccdc6Michael Jurka return; 6131637d6d64ac85d75b69b90fd976ed449046ccdc6Michael Jurka } 6148b805b17158886035b38261eb611d8641701ae43Michael Jurka AppWidgetHostView hostView = mLauncher. 6158b805b17158886035b38261eb611d8641701ae43Michael Jurka getAppWidgetHost().createView(getContext(), mWidgetLoadingId, pInfo); 616ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen info.boundWidget = hostView; 617ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mWidgetCleanupState = WIDGET_INFLATED; 618ef3dd6efe03c988be1fe980fbed75333017e6760Adam Cohen hostView.setVisibility(INVISIBLE); 6191f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(info.spanX, 6201f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen info.spanY, info, false); 6211f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen 6221f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen // We want the first widget layout to be the correct size. This will be important 6231f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen // for width size reporting to the AppWidgetManager. 6241f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen DragLayer.LayoutParams lp = new DragLayer.LayoutParams(unScaledSize[0], 6251f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen unScaledSize[1]); 6261f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen lp.x = lp.y = 0; 6271f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen lp.customPosition = true; 6281f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen hostView.setLayoutParams(lp); 629ef3dd6efe03c988be1fe980fbed75333017e6760Adam Cohen mLauncher.getDragLayer().addView(hostView); 630ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 631ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen }; 632ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen post(mInflateWidgetRunnable); 633ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 634ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 635ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 636ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void onShortPress(View v) { 637ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen // We are anticipating a long press, and we use this time to load bind and instantiate 638ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen // the widget. This will need to be cleaned up if it turns out no long press occurs. 6390e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen if (mCreateWidgetInfo != null) { 6400e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen // Just in case the cleanup process wasn't properly executed. This shouldn't happen. 6410e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen cleanupWidgetPreloading(false); 6420e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen } 6431b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen mCreateWidgetInfo = new PendingAddWidgetInfo((PendingAddWidgetInfo) v.getTag()); 644f1dcdf61132a6321d0c1c0eb670c6cf1493ab981Adam Cohen preloadWidget(mCreateWidgetInfo); 645ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 646ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 6470e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen private void cleanupWidgetPreloading(boolean widgetWasAdded) { 6480e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen if (!widgetWasAdded) { 6490e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen // If the widget was not added, we may need to do further cleanup. 6500e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen PendingAddWidgetInfo info = mCreateWidgetInfo; 6510e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen mCreateWidgetInfo = null; 65221a170b2e17621583f2800d5611459a0a939f560Adam Cohen 65321a170b2e17621583f2800d5611459a0a939f560Adam Cohen if (mWidgetCleanupState == WIDGET_PRELOAD_PENDING) { 65421a170b2e17621583f2800d5611459a0a939f560Adam Cohen // We never did any preloading, so just remove pending callbacks to do so 65521a170b2e17621583f2800d5611459a0a939f560Adam Cohen removeCallbacks(mBindWidgetRunnable); 65621a170b2e17621583f2800d5611459a0a939f560Adam Cohen removeCallbacks(mInflateWidgetRunnable); 65721a170b2e17621583f2800d5611459a0a939f560Adam Cohen } else if (mWidgetCleanupState == WIDGET_BOUND) { 65821a170b2e17621583f2800d5611459a0a939f560Adam Cohen // Delete the widget id which was allocated 65921a170b2e17621583f2800d5611459a0a939f560Adam Cohen if (mWidgetLoadingId != -1) { 66021a170b2e17621583f2800d5611459a0a939f560Adam Cohen mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId); 66121a170b2e17621583f2800d5611459a0a939f560Adam Cohen } 66221a170b2e17621583f2800d5611459a0a939f560Adam Cohen 66321a170b2e17621583f2800d5611459a0a939f560Adam Cohen // We never got around to inflating the widget, so remove the callback to do so. 6640e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen removeCallbacks(mInflateWidgetRunnable); 6650e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen } else if (mWidgetCleanupState == WIDGET_INFLATED) { 66621a170b2e17621583f2800d5611459a0a939f560Adam Cohen // Delete the widget id which was allocated 66721a170b2e17621583f2800d5611459a0a939f560Adam Cohen if (mWidgetLoadingId != -1) { 66821a170b2e17621583f2800d5611459a0a939f560Adam Cohen mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId); 66921a170b2e17621583f2800d5611459a0a939f560Adam Cohen } 67021a170b2e17621583f2800d5611459a0a939f560Adam Cohen 6710e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen // The widget was inflated and added to the DragLayer -- remove it. 6720e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen AppWidgetHostView widget = info.boundWidget; 6730e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen mLauncher.getDragLayer().removeView(widget); 6740e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen } 675ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 676ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED; 677ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mWidgetLoadingId = -1; 6780e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen mCreateWidgetInfo = null; 6790e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen PagedViewWidget.resetShortPressTarget(); 680ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 681ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 6827a326648c54922c60c32088e173c93068a82d107Adam Cohen @Override 6837a326648c54922c60c32088e173c93068a82d107Adam Cohen public void cleanUpShortPress(View v) { 6847a326648c54922c60c32088e173c93068a82d107Adam Cohen if (!mDraggingWidget) { 6850e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen cleanupWidgetPreloading(false); 6867a326648c54922c60c32088e173c93068a82d107Adam Cohen } 6877a326648c54922c60c32088e173c93068a82d107Adam Cohen } 688ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 68988c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen private boolean beginDraggingWidget(View v) { 6907a326648c54922c60c32088e173c93068a82d107Adam Cohen mDraggingWidget = true; 6914b576be59e58072cc03b5a8d36afb6a322513575Winson Chung // Get the widget preview as the drag representation 6924b576be59e58072cc03b5a8d36afb6a322513575Winson Chung ImageView image = (ImageView) v.findViewById(R.id.widget_preview); 6931ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag(); 6944b576be59e58072cc03b5a8d36afb6a322513575Winson Chung 69588c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and 69688c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen // we abort the drag. 69788c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen if (image.getDrawable() == null) { 69888c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen mDraggingWidget = false; 69988c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen return false; 70088c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen } 70188c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen 7024b576be59e58072cc03b5a8d36afb6a322513575Winson Chung // Compose the drag image 7031120e0355798391712f1d2e2b205f0bd3724770cWinson Chung Bitmap preview; 7041120e0355798391712f1d2e2b205f0bd3724770cWinson Chung Bitmap outline; 70572d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung float scale = 1f; 70605713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka Point previewPadding = null; 70705713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka 7081ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung if (createItemInfo instanceof PendingAddWidgetInfo) { 7099247892015dad231c5005aa021c3e3416265ed80Adam Cohen // This can happen in some weird cases involving multi-touch. We can't start dragging 7109247892015dad231c5005aa021c3e3416265ed80Adam Cohen // the widget if this is null, so we break out. 7119247892015dad231c5005aa021c3e3416265ed80Adam Cohen if (mCreateWidgetInfo == null) { 7129247892015dad231c5005aa021c3e3416265ed80Adam Cohen return false; 7139247892015dad231c5005aa021c3e3416265ed80Adam Cohen } 7149247892015dad231c5005aa021c3e3416265ed80Adam Cohen 7151b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen PendingAddWidgetInfo createWidgetInfo = mCreateWidgetInfo; 7161b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen createItemInfo = createWidgetInfo; 7171f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen int spanX = createItemInfo.spanX; 7181f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen int spanY = createItemInfo.spanY; 7191f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen int[] size = mLauncher.getWorkspace().estimateItemSize(spanX, spanY, 7201f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen createWidgetInfo, true); 7211ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung 72272d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung FastBitmapDrawable previewDrawable = (FastBitmapDrawable) image.getDrawable(); 72372d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung float minScale = 1.25f; 724dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka int maxWidth, maxHeight; 725dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka maxWidth = Math.min((int) (previewDrawable.getIntrinsicWidth() * minScale), size[0]); 726dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka maxHeight = Math.min((int) (previewDrawable.getIntrinsicHeight() * minScale), size[1]); 72705713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka 72805713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka int[] previewSizeBeforeScale = new int[1]; 72905713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka 730610ded21c79ae3da4c105c2d1921a30732468a69Svet Ganov preview = mWidgetPreviewLoader.generateWidgetPreview(createWidgetInfo.info, spanX, 731610ded21c79ae3da4c105c2d1921a30732468a69Svet Ganov spanY, maxWidth, maxHeight, null, previewSizeBeforeScale); 73205713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka 73305713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka // Compare the size of the drag preview to the preview in the AppsCustomize tray 73405713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka int previewWidthInAppsCustomize = Math.min(previewSizeBeforeScale[0], 73505713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka mWidgetPreviewLoader.maxWidthForWidgetPreview(spanX)); 73605713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka scale = previewWidthInAppsCustomize / (float) preview.getWidth(); 73705713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka 73805713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka // The bitmap in the AppsCustomize tray is always the the same size, so there 73905713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka // might be extra pixels around the preview itself - this accounts for that 74005713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka if (previewWidthInAppsCustomize < previewDrawable.getIntrinsicWidth()) { 74105713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka int padding = 74205713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka (previewDrawable.getIntrinsicWidth() - previewWidthInAppsCustomize) / 2; 74305713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka previewPadding = new Point(padding, 0); 74405713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka } 7451ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } else { 746dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag(); 747374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani // Widgets are only supported for current user, not for other profiles. 748374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani // Hence use myUserHandle(). 749374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.shortcutActivityInfo, 750374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani android.os.Process.myUserHandle()); 751dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka preview = Bitmap.createBitmap(icon.getIntrinsicWidth(), 752dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); 753dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka 7541120e0355798391712f1d2e2b205f0bd3724770cWinson Chung mCanvas.setBitmap(preview); 7554ca3922d9d4509b81005ab9625d6d00913911149Michael Jurka mCanvas.save(); 75605713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka WidgetPreviewLoader.renderDrawableToBitmap(icon, preview, 0, 0, 757dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); 7584ca3922d9d4509b81005ab9625d6d00913911149Michael Jurka mCanvas.restore(); 759aaf473c2bb6329b3b09ed2e19de6aae26077050cAdam Cohen mCanvas.setBitmap(null); 7601ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung createItemInfo.spanX = createItemInfo.spanY = 1; 7611ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } 7624b576be59e58072cc03b5a8d36afb6a322513575Winson Chung 7638c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka // Don't clip alpha values for the drag outline if we're using the default widget preview 7648c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka boolean clipAlpha = !(createItemInfo instanceof PendingAddWidgetInfo && 765610ded21c79ae3da4c105c2d1921a30732468a69Svet Ganov (((PendingAddWidgetInfo) createItemInfo).info.previewImage == 0)); 7668db7000140d3c35be92a4e07cf54ea6ec4ae3030Peter Ng 7671120e0355798391712f1d2e2b205f0bd3724770cWinson Chung // Save the preview for the outline generation, then dim the preview 7681120e0355798391712f1d2e2b205f0bd3724770cWinson Chung outline = Bitmap.createScaledBitmap(preview, preview.getWidth(), preview.getHeight(), 7691120e0355798391712f1d2e2b205f0bd3724770cWinson Chung false); 7701120e0355798391712f1d2e2b205f0bd3724770cWinson Chung 7714b576be59e58072cc03b5a8d36afb6a322513575Winson Chung // Start the drag 772641d71d6da6c77cc32e5d0f65ccae89caed1ac34Winson Chung mLauncher.lockScreenOrientation(); 7738c3339bde96d11fd1d7f818cd39e7438e309ffd1Michael Jurka mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, outline, clipAlpha); 7741120e0355798391712f1d2e2b205f0bd3724770cWinson Chung mDragController.startDrag(image, preview, this, createItemInfo, 77505713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka DragController.DRAG_ACTION_COPY, previewPadding, scale); 7761120e0355798391712f1d2e2b205f0bd3724770cWinson Chung outline.recycle(); 7771120e0355798391712f1d2e2b205f0bd3724770cWinson Chung preview.recycle(); 77888c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen return true; 7794b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } 7807d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung 781ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 782ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen protected boolean beginDragging(final View v) { 7834b576be59e58072cc03b5a8d36afb6a322513575Winson Chung if (!super.beginDragging(v)) return false; 7844b576be59e58072cc03b5a8d36afb6a322513575Winson Chung 7854b576be59e58072cc03b5a8d36afb6a322513575Winson Chung if (v instanceof PagedViewIcon) { 7864b576be59e58072cc03b5a8d36afb6a322513575Winson Chung beginDraggingApplication(v); 7874b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } else if (v instanceof PagedViewWidget) { 78888c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen if (!beginDraggingWidget(v)) { 78988c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen return false; 79088c5d2d8eb895904f4626fb5d2f3e693327de650Adam Cohen } 7914b576be59e58072cc03b5a8d36afb6a322513575Winson Chung } 792ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 793ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen // We delay entering spring-loaded mode slightly to make sure the UI 794ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen // thready is free of any work. 795ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen postDelayed(new Runnable() { 796ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen @Override 797ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void run() { 7981b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen // We don't enter spring-loaded mode if the drag has been cancelled 7991b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen if (mLauncher.getDragController().isDragging()) { 8001b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen // Dismiss the cling 8011b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen mLauncher.dismissAllAppsCling(null); 802ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 8031b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen // Reset the alpha on the dragged icon before we drag 8041b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen resetDrawableState(); 805ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 8061b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen // Go into spring loaded mode (must happen before we startDrag()) 8071b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen mLauncher.enterSpringLoadedDragMode(); 8081b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen } 809ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 81072d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung }, 150); 811ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 812785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung return true; 813785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 8141b36dc3f2bb643e3b9600755f1a98522e4efc2edAdam Cohen 815a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung /** 816a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung * Clean up after dragging. 817a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung * 818a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung * @param target where the item was dragged to (can be null if the item was flung) 819a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung */ 820a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung private void endDragging(View target, boolean isFlingToDelete, boolean success) { 821a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() && 822d4d7aa551ffdc80d810ff970fa72a6509960401eAdam Cohen !(target instanceof DeleteDropTarget))) { 823557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung // Exit spring loaded mode if we have not successfully dropped or have not handled the 824557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung // drop in Workspace 825557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung mLauncher.exitSpringLoadedDragMode(); 826557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 8274b919f813f4e5e0323a4c1747392551fce4a8758Winson Chung mLauncher.unlockScreenOrientation(false); 828785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 829785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 830785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung @Override 831a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka public View getContent() { 832a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka return null; 833a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka } 834a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka 835a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka @Override 836a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) { 83739e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka mInTransition = true; 83839e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka if (toWorkspace) { 83939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka cancelAllTasks(); 84039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 84139e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 84239e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka 84339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka @Override 844a35e35ae0ac2391b8928eb15bf91274aea96b115Michael Jurka public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) { 84539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 84639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka 84739e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka @Override 84839e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka public void onLauncherTransitionStep(Launcher l, float t) { 84939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 85039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka 85139e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka @Override 85239e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) { 85339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka mInTransition = false; 85439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka for (AsyncTaskPageData d : mDeferredSyncWidgetPageItems) { 85539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka onSyncWidgetPageItems(d); 85639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 85739e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka mDeferredSyncWidgetPageItems.clear(); 858f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka for (Runnable r : mDeferredPrepareLoadWidgetPreviewsTasks) { 859f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka r.run(); 860f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka } 861f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka mDeferredPrepareLoadWidgetPreviewsTasks.clear(); 8625e368ffbad2fb08e3eadab98eeefd4e1d05bdb2bMichael Jurka mForceDrawAllChildrenNextFrame = !toWorkspace; 86339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 86439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka 86539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka @Override 866a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete, 867a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung boolean success) { 868a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // Return early and wait for onFlingToDeleteCompleted if this was the result of a fling 869a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung if (isFlingToDelete) return; 870a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 871a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung endDragging(target, false, success); 872fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung 873fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung // Display an error message if the drag failed due to there not being enough space on the 874fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung // target layout we were dropping on. 875fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung if (!success) { 876fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung boolean showOutOfSpaceMessage = false; 877fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung if (target instanceof Workspace) { 878fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung int currentScreen = mLauncher.getCurrentWorkspaceScreen(); 879fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung Workspace workspace = (Workspace) target; 880fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen); 881c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen ItemInfo itemInfo = (ItemInfo) d.dragInfo; 882fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung if (layout != null) { 883fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung layout.calculateSpans(itemInfo); 884fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung showOutOfSpaceMessage = 885fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY); 886fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung } 887fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung } 888fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung if (showOutOfSpaceMessage) { 88993eef082ec2da802ee4507fb2ca729e550f833f1Winson Chung mLauncher.showOutOfSpaceMessage(false); 890fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung } 8917a326648c54922c60c32088e173c93068a82d107Adam Cohen 8927bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung d.deferDragViewCleanupPostAnimation = false; 893fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung } 8940e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen cleanupWidgetPreloading(success); 8957a326648c54922c60c32088e173c93068a82d107Adam Cohen mDraggingWidget = false; 896785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 897785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 898a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 899a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onFlingToDeleteCompleted() { 900a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // We just dismiss the drag when we fling, so cleanup here 901a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung endDragging(null, true, true); 9020e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen cleanupWidgetPreloading(false); 903a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung mDraggingWidget = false; 904a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 905a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 906a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 907043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public boolean supportsFlingToDelete() { 908a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung return true; 909043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 910043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 9117f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung @Override 9127f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung protected void onDetachedFromWindow() { 9137f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung super.onDetachedFromWindow(); 9140cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen cancelAllTasks(); 9150cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 9167f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung 917e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka public void clearAllWidgetPages() { 918e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka cancelAllTasks(); 919e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka int count = getChildCount(); 920e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka for (int i = 0; i < count; i++) { 921e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka View v = getPageAt(i); 922e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka if (v instanceof PagedViewGridLayout) { 923e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka ((PagedViewGridLayout) v).removeAllViewsOnPage(); 924e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka mDirtyPageContent.set(i, true); 925e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka } 926e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka } 927e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka } 928e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka 9290cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen private void cancelAllTasks() { 9307f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung // Clean up all the async tasks 9317f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 9327f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung while (iter.hasNext()) { 9337f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 9347f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung task.cancel(false); 9357f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung iter.remove(); 93639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka mDirtyPageContent.set(task.page, true); 9377ce9985d37e253a93617404d5991017e1ea81907Winson Chung 9387ce9985d37e253a93617404d5991017e1ea81907Winson Chung // We've already preallocated the views for the data to load into, so clear them as well 9397ce9985d37e253a93617404d5991017e1ea81907Winson Chung View v = getPageAt(task.page); 9407ce9985d37e253a93617404d5991017e1ea81907Winson Chung if (v instanceof PagedViewGridLayout) { 9417ce9985d37e253a93617404d5991017e1ea81907Winson Chung ((PagedViewGridLayout) v).removeAllViewsOnPage(); 9427ce9985d37e253a93617404d5991017e1ea81907Winson Chung } 9437f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung } 94483687b1e5bd887cb9eb3566fe27745c1b31d09f8Winson Chung mDeferredSyncWidgetPageItems.clear(); 945f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka mDeferredPrepareLoadWidgetPreviewsTasks.clear(); 9467f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung } 9477f0acdde9679eb545abb8bc5373e1938c420bf63Winson Chung 948785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void setContentType(ContentType type) { 9490cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen if (type == ContentType.Widgets) { 9500cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen invalidatePageData(mNumAppsPages, true); 9510cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } else if (type == ContentType.Applications) { 9520cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen invalidatePageData(0, true); 9530cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 954b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 955b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 9560cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen protected void snapToPage(int whichPage, int delta, int duration) { 9570cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen super.snapToPage(whichPage, delta, duration); 9580cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen updateCurrentTab(whichPage); 95968e4c64a67f4a40afac4cab44def461783f096a4Winson Chung 96068e4c64a67f4a40afac4cab44def461783f096a4Winson Chung // Update the thread priorities given the direction lookahead 96168e4c64a67f4a40afac4cab44def461783f096a4Winson Chung Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 96268e4c64a67f4a40afac4cab44def461783f096a4Winson Chung while (iter.hasNext()) { 96368e4c64a67f4a40afac4cab44def461783f096a4Winson Chung AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 96439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka int pageIndex = task.page; 96568e4c64a67f4a40afac4cab44def461783f096a4Winson Chung if ((mNextPage > mCurrentPage && pageIndex >= mCurrentPage) || 96668e4c64a67f4a40afac4cab44def461783f096a4Winson Chung (mNextPage < mCurrentPage && pageIndex <= mCurrentPage)) { 96768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung task.setThreadPriority(getThreadPriorityForPage(pageIndex)); 96868e4c64a67f4a40afac4cab44def461783f096a4Winson Chung } else { 96968e4c64a67f4a40afac4cab44def461783f096a4Winson Chung task.setThreadPriority(Process.THREAD_PRIORITY_LOWEST); 97068e4c64a67f4a40afac4cab44def461783f096a4Winson Chung } 97168e4c64a67f4a40afac4cab44def461783f096a4Winson Chung } 9720cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 9730cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 9740cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen private void updateCurrentTab(int currentPage) { 9750cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen AppsCustomizeTabHost tabHost = getTabHost(); 976c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung if (tabHost != null) { 977c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung String tag = tabHost.getCurrentTabTag(); 978c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung if (tag != null) { 979c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung if (currentPage >= mNumAppsPages && 980c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung !tag.equals(tabHost.getTabTagForContentType(ContentType.Widgets))) { 981c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung tabHost.setCurrentTabFromContent(ContentType.Widgets); 982c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung } else if (currentPage < mNumAppsPages && 983c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung !tag.equals(tabHost.getTabTagForContentType(ContentType.Applications))) { 984c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung tabHost.setCurrentTabFromContent(ContentType.Applications); 985c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung } 9866a8103c7efcaf6ea6e3170b36bf96dcfc1fa36b3Winson Chung } 9870cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 9880cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 9890cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 990785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung /* 991785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Apps PagedView implementation 992785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */ 99363257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung private void setVisibilityOnChildren(ViewGroup layout, int visibility) { 99463257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung int childCount = layout.getChildCount(); 99563257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung for (int i = 0; i < childCount; ++i) { 99663257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung layout.getChildAt(i).setVisibility(visibility); 99763257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung } 99863257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung } 999785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private void setupPage(PagedViewCellLayout layout) { 1000785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung layout.setCellCount(mCellCountX, mCellCountY); 1001785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung layout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap); 1002785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, 1003785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mPageLayoutPaddingRight, mPageLayoutPaddingBottom); 1004785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 100563257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung // Note: We force a measure here to get around the fact that when we do layout calculations 100663257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung // immediately after syncing, we don't have a proper width. That said, we already know the 100763257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung // expected page width, so we can actually optimize by hiding all the TextView-based 100863257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung // children that are expensive to measure, and let that happen naturally later. 100963257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung setVisibilityOnChildren(layout, View.GONE); 1010db1138b4efae89a3b5833547958a3606e5408a71Winson Chung int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST); 1011785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST); 101263257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung layout.setMinimumWidth(getPageContentWidth()); 1013785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung layout.measure(widthSpec, heightSpec); 101463257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung setVisibilityOnChildren(layout, View.VISIBLE); 1015785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 10160cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 1017f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung public void syncAppsPageItems(int page, boolean immediate) { 1018785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // ensure that we have the right number of items on the pages 1019fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung final boolean isRtl = isLayoutRtl(); 1020785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int numCells = mCellCountX * mCellCountY; 1021785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int startIndex = page * numCells; 1022785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int endIndex = Math.min(startIndex + numCells, mApps.size()); 102322f823d340710bcde587b18a1542570cbe0360f5Adam Cohen PagedViewCellLayout layout = (PagedViewCellLayout) getPageAt(page); 1024875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung 1025785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung layout.removeAllViewsOnPage(); 1026b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung ArrayList<Object> items = new ArrayList<Object>(); 1027b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung ArrayList<Bitmap> images = new ArrayList<Bitmap>(); 1028785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung for (int i = startIndex; i < endIndex; ++i) { 1029785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung ApplicationInfo info = mApps.get(i); 1030785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung PagedViewIcon icon = (PagedViewIcon) mLayoutInflater.inflate( 1031785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung R.layout.apps_customize_application, layout, false); 1032e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung icon.applyFromApplicationInfo(info, true, this); 1033785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung icon.setOnClickListener(this); 1034785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung icon.setOnLongClickListener(this); 1035785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung icon.setOnTouchListener(this); 1036c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung icon.setOnKeyListener(this); 1037785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 1038785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int index = i - startIndex; 1039785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int x = index % mCellCountX; 1040785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int y = index / mCellCountX; 1041fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung if (isRtl) { 1042fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung x = mCellCountX - x - 1; 1043fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung } 10446a70e9fc3c62cc83d6abe59323d622dc6cd224a7Winson Chung layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1)); 1045b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 1046b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung items.add(info); 1047b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung images.add(info.iconBitmap); 1048785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1049f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 105047639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka enableHwLayersOnVisiblePages(); 1051b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1052b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 1053b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung /** 105468e4c64a67f4a40afac4cab44def461783f096a4Winson Chung * A helper to return the priority for loading of the specified widget page. 105568e4c64a67f4a40afac4cab44def461783f096a4Winson Chung */ 105668e4c64a67f4a40afac4cab44def461783f096a4Winson Chung private int getWidgetPageLoadPriority(int page) { 105768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung // If we are snapping to another page, use that index as the target page index 105868e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int toPage = mCurrentPage; 105968e4c64a67f4a40afac4cab44def461783f096a4Winson Chung if (mNextPage > -1) { 106068e4c64a67f4a40afac4cab44def461783f096a4Winson Chung toPage = mNextPage; 106168e4c64a67f4a40afac4cab44def461783f096a4Winson Chung } 106268e4c64a67f4a40afac4cab44def461783f096a4Winson Chung 106368e4c64a67f4a40afac4cab44def461783f096a4Winson Chung // We use the distance from the target page as an initial guess of priority, but if there 106468e4c64a67f4a40afac4cab44def461783f096a4Winson Chung // are no pages of higher priority than the page specified, then bump up the priority of 106568e4c64a67f4a40afac4cab44def461783f096a4Winson Chung // the specified page. 106668e4c64a67f4a40afac4cab44def461783f096a4Winson Chung Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 106768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int minPageDiff = Integer.MAX_VALUE; 106868e4c64a67f4a40afac4cab44def461783f096a4Winson Chung while (iter.hasNext()) { 106968e4c64a67f4a40afac4cab44def461783f096a4Winson Chung AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 107039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka minPageDiff = Math.abs(task.page - toPage); 107168e4c64a67f4a40afac4cab44def461783f096a4Winson Chung } 107268e4c64a67f4a40afac4cab44def461783f096a4Winson Chung 107368e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int rawPageDiff = Math.abs(page - toPage); 107468e4c64a67f4a40afac4cab44def461783f096a4Winson Chung return rawPageDiff - Math.min(rawPageDiff, minPageDiff); 107568e4c64a67f4a40afac4cab44def461783f096a4Winson Chung } 107668e4c64a67f4a40afac4cab44def461783f096a4Winson Chung /** 1077b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * Return the appropriate thread priority for loading for a given page (we give the current 1078b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * page much higher priority) 1079b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung */ 1080b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung private int getThreadPriorityForPage(int page) { 1081b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung // TODO-APPS_CUSTOMIZE: detect number of cores and set thread priorities accordingly below 108268e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int pageDiff = getWidgetPageLoadPriority(page); 1083b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung if (pageDiff <= 0) { 108468e4c64a67f4a40afac4cab44def461783f096a4Winson Chung return Process.THREAD_PRIORITY_LESS_FAVORABLE; 1085b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } else if (pageDiff <= 1) { 108668e4c64a67f4a40afac4cab44def461783f096a4Winson Chung return Process.THREAD_PRIORITY_LOWEST; 1087b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } else { 108868e4c64a67f4a40afac4cab44def461783f096a4Winson Chung return Process.THREAD_PRIORITY_LOWEST; 1089b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1090785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1091f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung private int getSleepForPage(int page) { 109268e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int pageDiff = getWidgetPageLoadPriority(page); 1093f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung return Math.max(0, pageDiff * sPageSleepDelay); 1094f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung } 1095b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung /** 1096b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * Creates and executes a new AsyncTask to load a page of widget previews. 1097b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung */ 1098b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung private void prepareLoadWidgetPreviewsTask(int page, ArrayList<Object> widgets, 1099d294526ad99db70d882a1e11f2b0f878524163faWinson Chung int cellWidth, int cellHeight, int cellCountX) { 110068e4c64a67f4a40afac4cab44def461783f096a4Winson Chung 1101b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung // Prune all tasks that are no longer needed 1102b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 1103b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung while (iter.hasNext()) { 1104b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 110539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka int taskPage = task.page; 110668e4c64a67f4a40afac4cab44def461783f096a4Winson Chung if (taskPage < getAssociatedLowerPageBound(mCurrentPage) || 110768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung taskPage > getAssociatedUpperPageBound(mCurrentPage)) { 1108b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung task.cancel(false); 1109b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung iter.remove(); 1110b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } else { 111168e4c64a67f4a40afac4cab44def461783f096a4Winson Chung task.setThreadPriority(getThreadPriorityForPage(taskPage)); 1112b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1113b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1114b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 1115f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung // We introduce a slight delay to order the loading of side pages so that we don't thrash 111639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka final int sleepMs = getSleepForPage(page); 1117b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung AsyncTaskPageData pageData = new AsyncTaskPageData(page, widgets, cellWidth, cellHeight, 1118038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka new AsyncTaskCallback() { 1119b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung @Override 1120b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) { 1121f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung try { 1122099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung try { 1123099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung Thread.sleep(sleepMs); 1124099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } catch (Exception e) {} 1125099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung loadWidgetPreviewsInBackground(task, data); 1126099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } finally { 1127099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung if (task.isCancelled()) { 1128099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung data.cleanup(true); 1129099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } 1130099459377a737d885bbd8ac4d52e6884a103b1c7Winson Chung } 1131b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1132b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung }, 1133b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung new AsyncTaskCallback() { 1134b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung @Override 1135b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) { 113639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka mRunningTasks.remove(task); 113739e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka if (task.isCancelled()) return; 113839e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka // do cleanup inside onSyncWidgetPageItems 113939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka onSyncWidgetPageItems(data); 1140b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 11413f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka }, mWidgetPreviewLoader); 1142b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 1143b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung // Ensure that the task is appropriately prioritized and runs in parallel 11440cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page, 1145875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung AsyncTaskPageData.Type.LoadWidgetPreviewData); 114639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka t.setThreadPriority(getThreadPriorityForPage(page)); 1147b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung t.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pageData); 1148b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung mRunningTasks.add(t); 1149b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1150b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 1151785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung /* 1152785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Widgets PagedView implementation 1153785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */ 11544e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung private void setupPage(PagedViewGridLayout layout) { 1155785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, 1156785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mPageLayoutPaddingRight, mPageLayoutPaddingBottom); 115763257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung 115863257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung // Note: We force a measure here to get around the fact that when we do layout calculations 1159d52f3d84fc1df6b4c1ae1101eb937ae4eeb32e75Winson Chung // immediately after syncing, we don't have a proper width. 116063257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST); 116163257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST); 1162785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung layout.setMinimumWidth(getPageContentWidth()); 116363257c110a4ee54d5e8872c471cce254cf613c7aWinson Chung layout.measure(widthSpec, heightSpec); 1164785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 11650cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 1166038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka public void syncWidgetPageItems(final int page, final boolean immediate) { 11676a3fd3f042c8bfa7d83e29c1eeadff21323ab089Winson Chung int numItemsPerPage = mWidgetCountX * mWidgetCountY; 1168d294526ad99db70d882a1e11f2b0f878524163faWinson Chung 11694b576be59e58072cc03b5a8d36afb6a322513575Winson Chung // Calculate the dimensions of each cell we are giving to each widget 1170038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka final ArrayList<Object> items = new ArrayList<Object>(); 1171038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka int contentWidth = mWidgetSpacingLayout.getContentWidth(); 1172038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka final int cellWidth = ((contentWidth - mPageLayoutPaddingLeft - mPageLayoutPaddingRight 11736a3fd3f042c8bfa7d83e29c1eeadff21323ab089Winson Chung - ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX); 1174038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka int contentHeight = mWidgetSpacingLayout.getContentHeight(); 1175038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka final int cellHeight = ((contentHeight - mPageLayoutPaddingTop - mPageLayoutPaddingBottom 11766a3fd3f042c8bfa7d83e29c1eeadff21323ab089Winson Chung - ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY); 1177d294526ad99db70d882a1e11f2b0f878524163faWinson Chung 1178e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung // Prepare the set of widgets to load previews for in the background 117939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka int offset = (page - mNumAppsPages) * numItemsPerPage; 11806a3fd3f042c8bfa7d83e29c1eeadff21323ab089Winson Chung for (int i = offset; i < Math.min(offset + numItemsPerPage, mWidgets.size()); ++i) { 11816a3fd3f042c8bfa7d83e29c1eeadff21323ab089Winson Chung items.add(mWidgets.get(i)); 1182b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1183b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 1184e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung // Prepopulate the pages with the other widget info, and fill in the previews later 118539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka final PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page); 1186e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung layout.setColumnCount(layout.getCellCountX()); 1187e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung for (int i = 0; i < items.size(); ++i) { 1188e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung Object rawInfo = items.get(i); 1189e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung PendingAddItemInfo createItemInfo = null; 1190e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate( 1191e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung R.layout.apps_customize_widget, layout, false); 1192e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung if (rawInfo instanceof AppWidgetProviderInfo) { 1193e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung // Fill in the widget information 1194e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo; 1195e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung createItemInfo = new PendingAddWidgetInfo(info, null, null); 11961f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen 11971f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen // Determine the widget spans and min resize spans. 11982f093b6ad185967c129781526060288e983bc58aAdam Cohen int[] spanXY = Launcher.getSpanForWidget(mLauncher, info); 11991f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen createItemInfo.spanX = spanXY[0]; 12001f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen createItemInfo.spanY = spanXY[1]; 12012f093b6ad185967c129781526060288e983bc58aAdam Cohen int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, info); 12021f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen createItemInfo.minSpanX = minSpanXY[0]; 12031f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen createItemInfo.minSpanY = minSpanXY[1]; 12041f36270212e46b6ec0f27a0109ceaa9eb4a4995dAdam Cohen 12053f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka widget.applyFromAppWidgetProviderInfo(info, -1, spanXY, mWidgetPreviewLoader); 1206e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung widget.setTag(createItemInfo); 1207ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen widget.setShortPressListener(this); 1208e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung } else if (rawInfo instanceof ResolveInfo) { 1209e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung // Fill in the shortcuts information 1210e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung ResolveInfo info = (ResolveInfo) rawInfo; 1211dac8591072959f69eaa8c6319311fd111ae75db6Michael Jurka createItemInfo = new PendingAddShortcutInfo(info.activityInfo); 1212e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 1213e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung createItemInfo.componentName = new ComponentName(info.activityInfo.packageName, 1214e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung info.activityInfo.name); 12153f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka widget.applyFromResolveInfo(mPackageManager, info, mWidgetPreviewLoader); 1216e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung widget.setTag(createItemInfo); 1217e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung } 1218e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung widget.setOnClickListener(this); 1219e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung widget.setOnLongClickListener(this); 1220e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung widget.setOnTouchListener(this); 1221c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung widget.setOnKeyListener(this); 1222e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung 1223e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung // Layout each widget 1224e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung int ix = i % mWidgetCountX; 1225e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung int iy = i / mWidgetCountX; 1226e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung GridLayout.LayoutParams lp = new GridLayout.LayoutParams( 1227cc11f742586b57c576026b7756a46209fe793ea1Fabrice Di Meglio GridLayout.spec(iy, GridLayout.START), 1228e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung GridLayout.spec(ix, GridLayout.TOP)); 1229e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung lp.width = cellWidth; 1230e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung lp.height = cellHeight; 1231cc11f742586b57c576026b7756a46209fe793ea1Fabrice Di Meglio lp.setGravity(Gravity.TOP | Gravity.START); 1232e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung if (ix > 0) lp.leftMargin = mWidgetWidthGap; 1233e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung if (iy > 0) lp.topMargin = mWidgetHeightGap; 1234e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung layout.addView(widget, lp); 1235e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung } 1236e4a647f8793ce7823394db43d6af57f9eab8a340Winson Chung 1237038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka // wait until a call on onLayout to start loading, because 1238038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka // PagedViewWidget.getPreviewSize() will return 0 if it hasn't been laid out 1239038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka // TODO: can we do a measure/layout immediately? 1240038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka layout.setOnLayoutListener(new Runnable() { 1241038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka public void run() { 1242038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka // Load the widget previews 1243038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka int maxPreviewWidth = cellWidth; 1244038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka int maxPreviewHeight = cellHeight; 1245038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka if (layout.getChildCount() > 0) { 1246038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka PagedViewWidget w = (PagedViewWidget) layout.getChildAt(0); 1247038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka int[] maxSize = w.getPreviewSize(); 1248038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka maxPreviewWidth = maxSize[0]; 1249038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka maxPreviewHeight = maxSize[1]; 1250038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka } 125105713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka 12523f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka mWidgetPreviewLoader.setPreviewSize( 12533f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka maxPreviewWidth, maxPreviewHeight, mWidgetSpacingLayout); 1254038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka if (immediate) { 1255038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka AsyncTaskPageData data = new AsyncTaskPageData(page, items, 12563f4e070aa58d51dd136885b4d3e2e6c5d9f93ea0Michael Jurka maxPreviewWidth, maxPreviewHeight, null, null, mWidgetPreviewLoader); 1257038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka loadWidgetPreviewsInBackground(null, data); 1258038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka onSyncWidgetPageItems(data); 1259038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka } else { 1260f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka if (mInTransition) { 1261f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka mDeferredPrepareLoadWidgetPreviewsTasks.add(this); 1262f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka } else { 1263f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka prepareLoadWidgetPreviewsTask(page, items, 1264f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka maxPreviewWidth, maxPreviewHeight, mWidgetCountX); 1265f6a9690c3471a8114250f10d8c7c0f22f43ffb8bMichael Jurka } 1266038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka } 12673c69decd81c9ae964849e998fae6d22a505e4368Michael Jurka layout.setOnLayoutListener(null); 1268038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka } 1269038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka }); 1270f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung } 1271f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung private void loadWidgetPreviewsInBackground(AppsCustomizeAsyncTask task, 1272f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung AsyncTaskPageData data) { 127368e4c64a67f4a40afac4cab44def461783f096a4Winson Chung // loadWidgetPreviewsInBackground can be called without a task to load a set of widget 127468e4c64a67f4a40afac4cab44def461783f096a4Winson Chung // previews synchronously 1275f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung if (task != null) { 1276f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung // Ensure that this task starts running at the correct priority 1277f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung task.syncThreadPriority(); 1278f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung } 1279f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung 1280f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung // Load each of the widget/shortcut previews 1281f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung ArrayList<Object> items = data.items; 1282f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung ArrayList<Bitmap> images = data.generatedImages; 1283f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung int count = items.size(); 1284f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung for (int i = 0; i < count; ++i) { 1285f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung if (task != null) { 1286f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung // Ensure we haven't been cancelled yet 1287f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung if (task.isCancelled()) break; 1288f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung // Before work on each item, ensure that this task is running at the correct 1289f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung // priority 1290f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung task.syncThreadPriority(); 1291f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung } 1292f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung 129305713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka images.add(mWidgetPreviewLoader.getPreview(items.get(i))); 1294f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung } 1295b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1296b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 129739e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka private void onSyncWidgetPageItems(AsyncTaskPageData data) { 129839e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka if (mInTransition) { 129939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka mDeferredSyncWidgetPageItems.add(data); 130039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka return; 130146af2e89164b391b7a0049c6ce9048a2b7a7f644Winson Chung } 130239e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka try { 130339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka int page = data.page; 130439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page); 130539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka 130639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka ArrayList<Object> items = data.items; 130739e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka int count = items.size(); 130839e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka for (int i = 0; i < count; ++i) { 130939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka PagedViewWidget widget = (PagedViewWidget) layout.getChildAt(i); 131039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka if (widget != null) { 131139e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka Bitmap preview = data.generatedImages.get(i); 131239e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka widget.applyPreview(new FastBitmapDrawable(preview), i); 131339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 131439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 1315b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung 131647639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka enableHwLayersOnVisiblePages(); 131768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung 131839e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka // Update all thread priorities 131939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 132039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka while (iter.hasNext()) { 132139e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 132239e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka int pageIndex = task.page; 132339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka task.setThreadPriority(getThreadPriorityForPage(pageIndex)); 132439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } 132539e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka } finally { 132639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka data.cleanup(false); 132768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung } 1328b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 132946af2e89164b391b7a0049c6ce9048a2b7a7f644Winson Chung 1330785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung @Override 1331785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void syncPages() { 1332785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung removeAllViews(); 13330cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen cancelAllTasks(); 1334875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung 13350cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen Context context = getContext(); 13360cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen for (int j = 0; j < mNumWidgetPages; ++j) { 13370cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen PagedViewGridLayout layout = new PagedViewGridLayout(context, mWidgetCountX, 13380cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen mWidgetCountY); 13390cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen setupPage(layout); 134039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka addView(layout, new PagedView.LayoutParams(LayoutParams.MATCH_PARENT, 13410cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen LayoutParams.MATCH_PARENT)); 1342875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung } 1343875de7e1605f4fc8f04c804b5ac4bb9386189630Winson Chung 13440cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen for (int i = 0; i < mNumAppsPages; ++i) { 13450cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen PagedViewCellLayout layout = new PagedViewCellLayout(context); 13460cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen setupPage(layout); 13470cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen addView(layout); 1348785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1349785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 13500cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 1351785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung @Override 1352f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung public void syncPageItems(int page, boolean immediate) { 13530cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen if (page < mNumAppsPages) { 1354f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung syncAppsPageItems(page, immediate); 13550cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } else { 135639e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka syncWidgetPageItems(page, immediate); 1357785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1358785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1359785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 136022f823d340710bcde587b18a1542570cbe0360f5Adam Cohen // We want our pages to be z-ordered such that the further a page is to the left, the higher 136122f823d340710bcde587b18a1542570cbe0360f5Adam Cohen // it is in the z-order. This is important to insure touch events are handled correctly. 136222f823d340710bcde587b18a1542570cbe0360f5Adam Cohen View getPageAt(int index) { 136339e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka return getChildAt(indexToPage(index)); 136422f823d340710bcde587b18a1542570cbe0360f5Adam Cohen } 136522f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 1366ae4f155e090bf387b989fb738ee34ab045585711Adam Cohen @Override 1367ae4f155e090bf387b989fb738ee34ab045585711Adam Cohen protected int indexToPage(int index) { 1368ae4f155e090bf387b989fb738ee34ab045585711Adam Cohen return getChildCount() - index - 1; 1369ae4f155e090bf387b989fb738ee34ab045585711Adam Cohen } 1370ae4f155e090bf387b989fb738ee34ab045585711Adam Cohen 137122f823d340710bcde587b18a1542570cbe0360f5Adam Cohen // In apps customize, we have a scrolling effect which emulates pulling cards off of a stack. 137222f823d340710bcde587b18a1542570cbe0360f5Adam Cohen @Override 137322f823d340710bcde587b18a1542570cbe0360f5Adam Cohen protected void screenScrolled(int screenCenter) { 137452aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung final boolean isRtl = isLayoutRtl(); 137522f823d340710bcde587b18a1542570cbe0360f5Adam Cohen super.screenScrolled(screenCenter); 137622f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 137722f823d340710bcde587b18a1542570cbe0360f5Adam Cohen for (int i = 0; i < getChildCount(); i++) { 137822f823d340710bcde587b18a1542570cbe0360f5Adam Cohen View v = getPageAt(i); 137922f823d340710bcde587b18a1542570cbe0360f5Adam Cohen if (v != null) { 1380b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen float scrollProgress = getScrollProgress(screenCenter, v, i); 138122f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 138252aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung float interpolatedProgress; 138352aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung float translationX; 138452aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung float maxScrollProgress = Math.max(0, scrollProgress); 138552aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung float minScrollProgress = Math.min(0, scrollProgress); 138652aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung 138752aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung if (isRtl) { 138852aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung translationX = maxScrollProgress * v.getMeasuredWidth(); 138952aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung interpolatedProgress = mZInterpolator.getInterpolation(Math.abs(maxScrollProgress)); 139052aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung } else { 139152aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung translationX = minScrollProgress * v.getMeasuredWidth(); 139252aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung interpolatedProgress = mZInterpolator.getInterpolation(Math.abs(minScrollProgress)); 139352aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung } 139422f823d340710bcde587b18a1542570cbe0360f5Adam Cohen float scale = (1 - interpolatedProgress) + 139522f823d340710bcde587b18a1542570cbe0360f5Adam Cohen interpolatedProgress * TRANSITION_SCALE_FACTOR; 1396b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen 13972591f6a5202664faf8cde2b68361e3842ce76ba9Adam Cohen float alpha; 139852aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung if (isRtl && (scrollProgress > 0)) { 139952aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung alpha = mAlphaInterpolator.getInterpolation(1 - Math.abs(maxScrollProgress)); 140052aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung } else if (!isRtl && (scrollProgress < 0)) { 140152aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung alpha = mAlphaInterpolator.getInterpolation(1 - Math.abs(scrollProgress)); 14022591f6a5202664faf8cde2b68361e3842ce76ba9Adam Cohen } else { 140352aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung // On large screens we need to fade the page as it nears its leftmost position 14042591f6a5202664faf8cde2b68361e3842ce76ba9Adam Cohen alpha = mLeftScreenAlphaInterpolator.getInterpolation(1 - scrollProgress); 14052591f6a5202664faf8cde2b68361e3842ce76ba9Adam Cohen } 140622f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 140722f823d340710bcde587b18a1542570cbe0360f5Adam Cohen v.setCameraDistance(mDensity * CAMERA_DISTANCE); 140822f823d340710bcde587b18a1542570cbe0360f5Adam Cohen int pageWidth = v.getMeasuredWidth(); 140922f823d340710bcde587b18a1542570cbe0360f5Adam Cohen int pageHeight = v.getMeasuredHeight(); 1410b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen 1411b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen if (PERFORM_OVERSCROLL_ROTATION) { 141252aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung float xPivot = isRtl ? 1f - TRANSITION_PIVOT : TRANSITION_PIVOT; 141352aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung boolean isOverscrollingFirstPage = isRtl ? scrollProgress > 0 : scrollProgress < 0; 141452aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung boolean isOverscrollingLastPage = isRtl ? scrollProgress < 0 : scrollProgress > 0; 141552aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung 141652aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung if (i == 0 && isOverscrollingFirstPage) { 1417b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen // Overscroll to the left 141852aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung v.setPivotX(xPivot * pageWidth); 1419b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); 1420b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen scale = 1.0f; 1421b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen alpha = 1.0f; 1422b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen // On the first page, we don't want the page to have any lateral motion 1423ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen translationX = 0; 142452aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung } else if (i == getChildCount() - 1 && isOverscrollingLastPage) { 1425b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen // Overscroll to the right 142652aee60edcfe5a16e16523c1a4241ac4d8b3672dWinson Chung v.setPivotX((1 - xPivot) * pageWidth); 1427b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); 1428b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen scale = 1.0f; 1429b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen alpha = 1.0f; 1430b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen // On the last page, we don't want the page to have any lateral motion. 1431ebea84d1c95f4c38ba8cee46cd586fd757b4fce2Adam Cohen translationX = 0; 1432b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen } else { 1433b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen v.setPivotY(pageHeight / 2.0f); 1434b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen v.setPivotX(pageWidth / 2.0f); 1435b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen v.setRotationY(0f); 1436b5ba097015c4794fa822f30b38a60a7070a00097Adam Cohen } 143722f823d340710bcde587b18a1542570cbe0360f5Adam Cohen } 143822f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 143922f823d340710bcde587b18a1542570cbe0360f5Adam Cohen v.setTranslationX(translationX); 144022f823d340710bcde587b18a1542570cbe0360f5Adam Cohen v.setScaleX(scale); 144122f823d340710bcde587b18a1542570cbe0360f5Adam Cohen v.setScaleY(scale); 144222f823d340710bcde587b18a1542570cbe0360f5Adam Cohen v.setAlpha(alpha); 14434e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen 14444e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen // If the view has 0 alpha, we set it to be invisible so as to prevent 14454e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen // it from accepting touches 14468b805b17158886035b38261eb611d8641701ae43Michael Jurka if (alpha == 0) { 14474e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen v.setVisibility(INVISIBLE); 14484e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen } else if (v.getVisibility() != VISIBLE) { 14494e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen v.setVisibility(VISIBLE); 14504e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen } 145122f823d340710bcde587b18a1542570cbe0360f5Adam Cohen } 145222f823d340710bcde587b18a1542570cbe0360f5Adam Cohen } 145347639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka 145447639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka enableHwLayersOnVisiblePages(); 145547639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 145647639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka 145747639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka private void enableHwLayersOnVisiblePages() { 145847639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka final int screenCount = getChildCount(); 145947639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka 146047639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka getVisiblePages(mTempVisiblePagesRange); 146147639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka int leftScreen = mTempVisiblePagesRange[0]; 146247639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka int rightScreen = mTempVisiblePagesRange[1]; 146347639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka int forceDrawScreen = -1; 146447639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka if (leftScreen == rightScreen) { 146547639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka // make sure we're caching at least two pages always 146647639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka if (rightScreen < screenCount - 1) { 146747639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka rightScreen++; 146847639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka forceDrawScreen = rightScreen; 146947639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } else if (leftScreen > 0) { 147047639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka leftScreen--; 147147639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka forceDrawScreen = leftScreen; 147247639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 147347639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } else { 147447639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka forceDrawScreen = leftScreen + 1; 147547639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 147647639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka 147747639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka for (int i = 0; i < screenCount; i++) { 147847639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka final View layout = (View) getPageAt(i); 147947639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka if (!(leftScreen <= i && i <= rightScreen && 148047639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka (i == forceDrawScreen || shouldDrawChild(layout)))) { 148147639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka layout.setLayerType(LAYER_TYPE_NONE, null); 148247639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 148347639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 148447639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka 148547639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka for (int i = 0; i < screenCount; i++) { 148647639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka final View layout = (View) getPageAt(i); 148747639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka 148847639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka if (leftScreen <= i && i <= rightScreen && 148947639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka (i == forceDrawScreen || shouldDrawChild(layout))) { 149047639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka if (layout.getLayerType() != LAYER_TYPE_HARDWARE) { 149147639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka layout.setLayerType(LAYER_TYPE_HARDWARE, null); 149247639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 149347639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 149447639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka } 149522f823d340710bcde587b18a1542570cbe0360f5Adam Cohen } 149622f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 149722f823d340710bcde587b18a1542570cbe0360f5Adam Cohen protected void overScroll(float amount) { 1498cff6af81d721415785bddc2efd74e179d2def9daAdam Cohen acceleratedOverScroll(amount); 149922f823d340710bcde587b18a1542570cbe0360f5Adam Cohen } 150022f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 1501785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung /** 1502785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Used by the parent to get the content width to set the tab bar to 1503785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * @return 1504785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */ 1505785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public int getPageContentWidth() { 1506785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung return mContentWidth; 1507785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1508785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 1509b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung @Override 1510b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung protected void onPageEndMoving() { 1511b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung super.onPageEndMoving(); 15125e368ffbad2fb08e3eadab98eeefd4e1d05bdb2bMichael Jurka mForceDrawAllChildrenNextFrame = true; 15135afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung // We reset the save index when we change pages so that it will be recalculated on next 15145afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung // rotation 15155afbf7bdd6f6879124c9b8283e005fe57f310d02Winson Chung mSaveInstanceStateItemIndex = -1; 1516b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung } 1517b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung 1518785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung /* 1519785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * AllAppsView implementation 1520785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */ 1521785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void setup(Launcher launcher, DragController dragController) { 1522785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mLauncher = launcher; 1523785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mDragController = dragController; 1524785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 15259802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung 15269802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung /** 15279802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung * We should call thise method whenever the core data changes (mApps, mWidgets) so that we can 15289802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung * appropriately determine when to invalidate the PagedView page data. In cases where the data 15299802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung * has yet to be set, we can requestLayout() and wait for onDataReady() to be called in the 15309802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung * next onMeasure() pass, which will trigger an invalidatePageData() itself. 15319802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung */ 15329802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung private void invalidateOnDataChange() { 15339802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung if (!isDataReady()) { 15349802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung // The next layout pass will trigger data-ready if both widgets and apps are set, so 15359802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung // request a layout to trigger the page data when ready. 15369802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung requestLayout(); 15379802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung } else { 15389802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung cancelAllTasks(); 15399802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung invalidatePageData(); 15409802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung } 15419802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung } 15429802ac9024b7bef300c6c9eb46aa63eb04697b28Winson Chung 1543785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void setApps(ArrayList<ApplicationInfo> list) { 1544785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mApps = list; 15451190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung Collections.sort(mApps, LauncherModel.getAppNameComparator()); 1546c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka updatePageCountsAndInvalidateData(); 1547785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1548374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani 1549785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) { 1550785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // We add it in place, in alphabetical order 1551785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int count = list.size(); 1552785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung for (int i = 0; i < count; ++i) { 1553785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung ApplicationInfo info = list.get(i); 15541190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung int index = Collections.binarySearch(mApps, info, LauncherModel.getAppNameComparator()); 1555785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung if (index < 0) { 1556785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mApps.add(-(index + 1), info); 1557785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1558785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1559785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1560785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void addApps(ArrayList<ApplicationInfo> list) { 1561785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung addAppsWithoutInvalidate(list); 1562c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka updatePageCountsAndInvalidateData(); 1563785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1564785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) { 1565785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung ComponentName removeComponent = item.intent.getComponent(); 1566785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int length = list.size(); 1567785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung for (int i = 0; i < length; ++i) { 1568785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung ApplicationInfo info = list.get(i); 1569374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani if (info.user.equals(item.user) 1570374753cabf05cde1ad669d07bde47e34fdcbe499Amith Yamasani && info.intent.getComponent().equals(removeComponent)) { 1571785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung return i; 1572785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1573785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1574785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung return -1; 1575785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1576785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private void removeAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) { 1577785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // loop through all the apps and remove apps that have the same component 1578785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int length = list.size(); 1579785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung for (int i = 0; i < length; ++i) { 1580785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung ApplicationInfo info = list.get(i); 1581785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung int removeIndex = findAppByComponent(mApps, info); 1582785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung if (removeIndex > -1) { 1583785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mApps.remove(removeIndex); 1584785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1585785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1586785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 158783892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung public void removeApps(ArrayList<ApplicationInfo> appInfos) { 158883892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung removeAppsWithoutInvalidate(appInfos); 1589c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka updatePageCountsAndInvalidateData(); 1590785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1591785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void updateApps(ArrayList<ApplicationInfo> list) { 1592785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // We remove and re-add the updated applications list because it's properties may have 1593785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // changed (ie. the title), and this will ensure that the items will be in their proper 1594785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // place in the list. 1595785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung removeAppsWithoutInvalidate(list); 1596785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung addAppsWithoutInvalidate(list); 1597c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka updatePageCountsAndInvalidateData(); 1598785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 159935aa14d5e33e4f5cccb9fd23be1047f26d67b409Michael Jurka 1600785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void reset() { 1601649668f7af9ef730466082f935831c901cafc74aWinson Chung // If we have reset, then we should not continue to restore the previous state 1602649668f7af9ef730466082f935831c901cafc74aWinson Chung mSaveInstanceStateItemIndex = -1; 1603649668f7af9ef730466082f935831c901cafc74aWinson Chung 1604b64d36e6f8006b3ea5a6c2951af4cf8dea72d08eAdam Cohen AppsCustomizeTabHost tabHost = getTabHost(); 1605b64d36e6f8006b3ea5a6c2951af4cf8dea72d08eAdam Cohen String tag = tabHost.getCurrentTabTag(); 16066a8103c7efcaf6ea6e3170b36bf96dcfc1fa36b3Winson Chung if (tag != null) { 16076a8103c7efcaf6ea6e3170b36bf96dcfc1fa36b3Winson Chung if (!tag.equals(tabHost.getTabTagForContentType(ContentType.Applications))) { 16086a8103c7efcaf6ea6e3170b36bf96dcfc1fa36b3Winson Chung tabHost.setCurrentTabFromContent(ContentType.Applications); 16096a8103c7efcaf6ea6e3170b36bf96dcfc1fa36b3Winson Chung } 1610b64d36e6f8006b3ea5a6c2951af4cf8dea72d08eAdam Cohen } 1611649668f7af9ef730466082f935831c901cafc74aWinson Chung 1612b64d36e6f8006b3ea5a6c2951af4cf8dea72d08eAdam Cohen if (mCurrentPage != 0) { 1613b64d36e6f8006b3ea5a6c2951af4cf8dea72d08eAdam Cohen invalidatePageData(0); 1614b64d36e6f8006b3ea5a6c2951af4cf8dea72d08eAdam Cohen } 16150cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } 16160cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 16170cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen private AppsCustomizeTabHost getTabHost() { 16180cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen return (AppsCustomizeTabHost) mLauncher.findViewById(R.id.apps_customize_pane); 1619785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 16200cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 1621785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void dumpState() { 1622785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // TODO: Dump information related to current list of Applications, Widgets, etc. 16230e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen ApplicationInfo.dumpApplicationInfoList(TAG, "mApps", mApps); 16240e56cc9fd6814af5813e73ba7a71bf1d51d4208aAdam Cohen dumpAppWidgetProviderInfoList(TAG, "mWidgets", mWidgets); 1625785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 16264e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen 1627785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private void dumpAppWidgetProviderInfoList(String tag, String label, 1628d294526ad99db70d882a1e11f2b0f878524163faWinson Chung ArrayList<Object> list) { 1629785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung Log.d(tag, label + " size=" + list.size()); 16301ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung for (Object i: list) { 16311ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung if (i instanceof AppWidgetProviderInfo) { 16321ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung AppWidgetProviderInfo info = (AppWidgetProviderInfo) i; 16331ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung Log.d(tag, " label=\"" + info.label + "\" previewImage=" + info.previewImage 16341ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung + " resizeMode=" + info.resizeMode + " configure=" + info.configure 16351ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung + " initialLayout=" + info.initialLayout 16361ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight); 16371ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } else if (i instanceof ResolveInfo) { 16381ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung ResolveInfo info = (ResolveInfo) i; 16391ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung Log.d(tag, " label=\"" + info.loadLabel(mPackageManager) + "\" icon=" 16401ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung + info.icon); 16411ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } 1642785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1643785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 16444e84401aa8f7c724190ffd2898d2eb939c019e82Adam Cohen 1645785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public void surrender() { 1646785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we 1647785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung // should stop this now. 16484b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung 16494b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung // Stop all background tasks 16504b0ed8c09ebc6afd97ff8b0de6a9617f6469ad1aWinson Chung cancelAllTasks(); 1651785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 1652007c69867d821ea2b271398577a8b3440b3a7046Winson Chung 1653e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung @Override 1654e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung public void iconPressed(PagedViewIcon icon) { 1655e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung // Reset the previously pressed icon and store a reference to the pressed icon so that 1656e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung // we can reset it on return to Launcher (in Launcher.onResume()) 1657e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung if (mPressedIcon != null) { 1658e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung mPressedIcon.resetDrawableState(); 1659e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung } 1660e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung mPressedIcon = icon; 1661e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung } 1662e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung 1663e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung public void resetDrawableState() { 1664e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung if (mPressedIcon != null) { 1665e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung mPressedIcon.resetDrawableState(); 1666e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung mPressedIcon = null; 1667e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung } 1668e4e506660ba93ae2c4f1cb0b41378cf148c85e2bWinson Chung } 166968e4c64a67f4a40afac4cab44def461783f096a4Winson Chung 1670b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung /* 1671b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * We load an extra page on each side to prevent flashes from scrolling and loading of the 1672b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung * widget previews in the background with the AsyncTasks. 1673b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung */ 167468e4c64a67f4a40afac4cab44def461783f096a4Winson Chung final static int sLookBehindPageCount = 2; 167568e4c64a67f4a40afac4cab44def461783f096a4Winson Chung final static int sLookAheadPageCount = 2; 1676b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung protected int getAssociatedLowerPageBound(int page) { 167768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung final int count = getChildCount(); 167868e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1); 167968e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int windowMinIndex = Math.max(Math.min(page - sLookBehindPageCount, count - windowSize), 0); 168068e4c64a67f4a40afac4cab44def461783f096a4Winson Chung return windowMinIndex; 1681b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 1682b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung protected int getAssociatedUpperPageBound(int page) { 1683b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung final int count = getChildCount(); 168468e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1); 168568e4c64a67f4a40afac4cab44def461783f096a4Winson Chung int windowMaxIndex = Math.min(Math.max(page + sLookAheadPageCount, windowSize - 1), 168668e4c64a67f4a40afac4cab44def461783f096a4Winson Chung count - 1); 168768e4c64a67f4a40afac4cab44def461783f096a4Winson Chung return windowMaxIndex; 1688b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung } 16896a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung 16906a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung @Override 16916a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung protected String getCurrentPageDescription() { 16926a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage; 16936a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung int stringId = R.string.default_scroll_format; 1694d3357b186d55816e682b3012cfccd2d7a0680678Adam Cohen int count = 0; 1695d3357b186d55816e682b3012cfccd2d7a0680678Adam Cohen 16960cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen if (page < mNumAppsPages) { 16976a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung stringId = R.string.apps_customize_apps_scroll_format; 1698d3357b186d55816e682b3012cfccd2d7a0680678Adam Cohen count = mNumAppsPages; 16990cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen } else { 17000cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen page -= mNumAppsPages; 17016a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung stringId = R.string.apps_customize_widgets_scroll_format; 1702d3357b186d55816e682b3012cfccd2d7a0680678Adam Cohen count = mNumWidgetPages; 17036a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung } 17040cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen 17058b805b17158886035b38261eb611d8641701ae43Michael Jurka return String.format(getContext().getString(stringId), page + 1, count); 17066a0f57dfafced837a2a282d8feec28d5418be3b9Winson Chung } 1707785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung} 1708