AppsCustomizePagedView.java revision c10ba1396f49cde2faacb7001e7e97fcee325507
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2011 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage com.android.launcher2; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Guptaimport android.animation.AnimatorSet; 20d51834bdfad0cd3142ac464ab3a3b0db14f884c3Deepanshu Guptaimport android.animation.ObjectAnimator; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.animation.ValueAnimator; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.appwidget.AppWidgetHostView; 2337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport android.appwidget.AppWidgetManager; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.appwidget.AppWidgetProviderInfo; 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.ComponentName; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.Context; 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.Intent; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.pm.PackageManager; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.pm.ResolveInfo; 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.res.Configuration; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.res.Resources; 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.content.res.TypedArray; 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Bitmap; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Bitmap.Config; 35eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Guptaimport android.graphics.Canvas; 36eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Guptaimport android.graphics.ColorMatrix; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.ColorMatrixColorFilter; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Insets; 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.MaskFilter; 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Matrix; 414dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsenimport android.graphics.Paint; 42eb26f5cecd5366b29b3cb746a7edaf3769f40480Deepanshu Guptaimport android.graphics.PorterDuff; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Rect; 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.RectF; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.Shader; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.TableMaskFilter; 47ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Guptaimport android.graphics.drawable.BitmapDrawable; 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.drawable.Drawable; 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.os.AsyncTask; 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.os.Process; 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.AttributeSet; 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.Log; 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.Gravity; 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.KeyEvent; 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.LayoutInflater; 56d51834bdfad0cd3142ac464ab3a3b0db14f884c3Deepanshu Guptaimport android.view.MotionEvent; 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.View; 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.ViewGroup; 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.animation.AccelerateInterpolator; 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.animation.DecelerateInterpolator; 61e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Guptaimport android.widget.GridLayout; 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.widget.ImageView; 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.widget.LinearLayout; 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.widget.Toast; 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.launcher.R; 67664d6f1fe4d6dfa742b3e98051f924dbc190f8caDeepanshu Guptaimport com.android.launcher2.DropTarget.DragObject; 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 69b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Guptaimport java.util.ArrayList; 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Collections; 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Iterator; 72b9b8aef94e5bad8f5f03f686a2d3d8a09c045a7bDeepanshu Guptaimport java.util.List; 73d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Guptaimport java.lang.ref.WeakReference; 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 75d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta/** 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * A simple callback interface which also provides the results of the task. 77d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta */ 78e8a04cd5a68a5e5aa78a4f40b3269c86cc3f152fIan Pedowitzinterface AsyncTaskCallback { 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data); 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The data needed to perform either of the custom AsyncTasks. 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass AsyncTaskPageData { 866e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown enum Type { 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LoadWidgetPreviewData 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 90e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta AsyncTaskPageData(int p, ArrayList<Object> l, ArrayList<Bitmap> si, AsyncTaskCallback bgR, 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskCallback postR) { 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski page = p; 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski items = l; 94d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta sourceImages = si; 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generatedImages = new ArrayList<Bitmap>(); 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxImageWidth = maxImageHeight = -1; 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski doInBackgroundCallback = bgR; 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski postExecuteCallback = postR; 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskPageData(int p, ArrayList<Object> l, int cw, int ch, AsyncTaskCallback bgR, 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskCallback postR) { 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski page = p; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski items = l; 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generatedImages = new ArrayList<Bitmap>(); 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxImageWidth = cw; 1062bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta maxImageHeight = ch; 1072bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta doInBackgroundCallback = bgR; 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski postExecuteCallback = postR; 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void cleanup(boolean cancelled) { 11185d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta // Clean up any references to source/generated bitmaps 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (sourceImages != null) { 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cancelled) { 1140ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta for (Bitmap b : sourceImages) { 11591253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta b.recycle(); 1160ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta } 1170ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta } 1180ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta sourceImages.clear(); 1190ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta } 1200ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta if (generatedImages != null) { 12191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta if (cancelled) { 122d51834bdfad0cd3142ac464ab3a3b0db14f884c3Deepanshu Gupta for (Bitmap b : generatedImages) { 1230ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta b.recycle(); 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generatedImages.clear(); 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 12937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta int page; 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<Object> items; 131664d6f1fe4d6dfa742b3e98051f924dbc190f8caDeepanshu Gupta ArrayList<Bitmap> sourceImages; 132d15459197f71f8cc940e2b057b399117df282f2cDiego Perez ArrayList<Bitmap> generatedImages; 133d15459197f71f8cc940e2b057b399117df282f2cDiego Perez int maxImageWidth; 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxImageHeight; 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskCallback doInBackgroundCallback; 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskCallback postExecuteCallback; 13791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta} 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 140d758e042ce08c46712db3db2d63fc84795028dfeDeepanshu Gupta * A generic template for an async task used in AppsCustomize. 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass AppsCustomizeAsyncTask extends AsyncTask<AsyncTaskPageData, Void, AsyncTaskPageData> { 143bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta AppsCustomizeAsyncTask(int p, AsyncTaskPageData.Type ty) { 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski page = p; 145eb26f5cecd5366b29b3cb746a7edaf3769f40480Deepanshu Gupta threadPriority = Process.THREAD_PRIORITY_DEFAULT; 14691253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta dataType = ty; 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected AsyncTaskPageData doInBackground(AsyncTaskPageData... params) { 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (params.length != 1) return null; 15191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta // Load each of the widget previews in the background 152dfeffd4c0ae165a3f225b818ef8d6f5d1cb89a2cDeepanshu Gupta params[0].doInBackgroundCallback.run(this, params[0]); 153f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta return params[0]; 154d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 155490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta @Override 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void onPostExecute(AsyncTaskPageData result) { 157b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta // All the widget previews are loaded, so we can just callback to inflate the page 158b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta result.postExecuteCallback.run(this, result); 159b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta } 160b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta 161b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta void setThreadPriority(int p) { 162b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta threadPriority = p; 163b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta } 16491253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta void syncThreadPriority() { 165b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta Process.setThreadPriority(threadPriority); 166b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta } 167b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta 168b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta // The page that this async task is associated with 169b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta AsyncTaskPageData.Type dataType; 170b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta int page; 171af0f3bda17ee3de4ad3560c9a675527b20e2af5fSiva Velusamy int threadPriority; 172af0f3bda17ee3de4ad3560c9a675527b20e2af5fSiva Velusamy} 173b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta 174b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Guptaabstract class WeakReferenceThreadLocal<T> { 175b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta private ThreadLocal<WeakReference<T>> mThreadLocal; 176b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta public WeakReferenceThreadLocal() { 177b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta mThreadLocal = new ThreadLocal<WeakReference<T>>(); 178b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta } 179f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski abstract T initialValue(); 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void set(T t) { 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mThreadLocal.set(new WeakReference<T>(t)); 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public T get() { 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski WeakReference<T> reference = mThreadLocal.get(); 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski T obj; 189d51834bdfad0cd3142ac464ab3a3b0db14f884c3Deepanshu Gupta if (reference == null) { 19037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta obj = initialValue(); 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mThreadLocal.set(new WeakReference<T>(obj)); 1928930cb4f37ff0fbde65f7afd4bbe06ab77677f78Deepanshu Gupta return obj; 1938930cb4f37ff0fbde65f7afd4bbe06ab77677f78Deepanshu Gupta } else { 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski obj = reference.get(); 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (obj == null) { 19637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta obj = initialValue(); 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mThreadLocal.set(new WeakReference<T>(obj)); 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return obj; 2002ea852541fd7c7af14b6919c5c2f57584b896d2bDeepanshu Gupta } 2012ea852541fd7c7af14b6919c5c2f57584b896d2bDeepanshu Gupta } 2022ea852541fd7c7af14b6919c5c2f57584b896d2bDeepanshu Gupta} 2032ea852541fd7c7af14b6919c5c2f57584b896d2bDeepanshu Gupta 2042ea852541fd7c7af14b6919c5c2f57584b896d2bDeepanshu Guptaclass CanvasCache extends WeakReferenceThreadLocal<Canvas> { 2052ea852541fd7c7af14b6919c5c2f57584b896d2bDeepanshu Gupta @Override 206d51834bdfad0cd3142ac464ab3a3b0db14f884c3Deepanshu Gupta protected Canvas initialValue() { 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new Canvas(); 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 2108930cb4f37ff0fbde65f7afd4bbe06ab77677f78Deepanshu Gupta 2118930cb4f37ff0fbde65f7afd4bbe06ab77677f78Deepanshu Guptaclass PaintCache extends WeakReferenceThreadLocal<Paint> { 2128930cb4f37ff0fbde65f7afd4bbe06ab77677f78Deepanshu Gupta @Override 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected Paint initialValue() { 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 215664d6f1fe4d6dfa742b3e98051f924dbc190f8caDeepanshu Gupta } 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass BitmapCache extends WeakReferenceThreadLocal<Bitmap> { 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 22037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta protected Bitmap initialValue() { 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass RectCache extends WeakReferenceThreadLocal<Rect> { 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 227e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta protected Rect initialValue() { 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return new Rect(); 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 23237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta/** 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The Apps/Customize page that displays all the applications, widgets, and shortcuts. 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic class AppsCustomizePagedView extends PagedViewWithDraggableItems implements 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AllAppsView, View.OnClickListener, View.OnKeyListener, DragSource, 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener, 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LauncherTransitionable { 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static final String TAG = "AppsCustomizePagedView"; 240e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The different content types that this paged view can show. 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public enum ContentType { 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Applications, 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Widgets 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Refs 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Launcher mLauncher; 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private DragController mDragController; 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final LayoutInflater mLayoutInflater; 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final PackageManager mPackageManager; 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2550ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta // Save and Restore 2560ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta private int mSaveInstanceStateItemIndex = -1; 2570ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta private PagedViewIcon mPressedIcon; 2580ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta 2590ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta // Content 2600ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta private ArrayList<ApplicationInfo> mApps; 2610ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta private ArrayList<Object> mWidgets; 2620ff4568ca07c16f2ad4c61872995200115292ecfDeepanshu Gupta 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Cling 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mHasShownAllAppsCling; 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mClingFocusedX; 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mClingFocusedY; 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Caching 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Canvas mCanvas; 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Drawable mDefaultWidgetBackground; 27137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta private IconCache mIconCache; 27237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Dimens 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mContentWidth; 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mAppIconSize; 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mMaxAppCellCountX, mMaxAppCellCountY; 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mWidgetCountX, mWidgetCountY; 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mWidgetWidthGap, mWidgetHeightGap; 279eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Gupta private final float sWidgetPreviewIconPaddingPercentage = 0.25f; 280eaf1853b98d7bf2c3d693ad702050968ef0a404cDeepanshu Gupta private PagedViewCellLayout mWidgetSpacingLayout; 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mNumAppsPages; 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int mNumWidgetPages; 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Relating to the scroll and overscroll effects 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Workspace.ZInterpolator mZInterpolator = new Workspace.ZInterpolator(0.5f); 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static float CAMERA_DISTANCE = 6500; 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static float TRANSITION_SCALE_FACTOR = 0.74f; 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static float TRANSITION_PIVOT = 0.65f; 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static float TRANSITION_MAX_ROTATION = 22; 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final boolean PERFORM_OVERSCROLL_ROTATION = true; 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private AccelerateInterpolator mAlphaInterpolator = new AccelerateInterpolator(0.9f); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private DecelerateInterpolator mLeftScreenAlphaInterpolator = new DecelerateInterpolator(4); 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Previews & outlines 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<AppsCustomizeAsyncTask> mRunningTasks; 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private static final int sPageSleepDelay = 200; 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Runnable mInflateWidgetRunnable = null; 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Runnable mBindWidgetRunnable = null; 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static final int WIDGET_NO_CLEANUP_REQUIRED = -1; 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static final int WIDGET_PRELOAD_PENDING = 0; 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static final int WIDGET_BOUND = 1; 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski static final int WIDGET_INFLATED = 2; 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED; 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int mWidgetLoadingId = -1; 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAddWidgetInfo mCreateWidgetInfo = null; 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mDraggingWidget = false; 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Deferral of loading widget previews during launcher transitions 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mInTransition; 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private ArrayList<AsyncTaskPageData> mDeferredSyncWidgetPageItems = 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new ArrayList<AsyncTaskPageData>(); 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private ArrayList<Runnable> mDeferredPrepareLoadWidgetPreviewsTasks = 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new ArrayList<Runnable>(); 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Used for drawing shortcut previews 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BitmapCache mCachedShortcutPreviewBitmap = new BitmapCache(); 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PaintCache mCachedShortcutPreviewPaint = new PaintCache(); 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CanvasCache mCachedShortcutPreviewCanvas = new CanvasCache(); 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Used for drawing widget previews 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski CanvasCache mCachedAppWidgetPreviewCanvas = new CanvasCache(); 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RectCache mCachedAppWidgetPreviewSrcRect = new RectCache(); 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski RectCache mCachedAppWidgetPreviewDestRect = new RectCache(); 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PaintCache mCachedAppWidgetPreviewPaint = new PaintCache(); 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta public AppsCustomizePagedView(Context context, AttributeSet attrs) { 32891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta super(context, attrs); 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLayoutInflater = LayoutInflater.from(context); 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPackageManager = context.getPackageManager(); 33191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta mApps = new ArrayList<ApplicationInfo>(); 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgets = new ArrayList<Object>(); 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIconCache = ((LauncherApplication) context.getApplicationContext()).getIconCache(); 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCanvas = new Canvas(); 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mRunningTasks = new ArrayList<AppsCustomizeAsyncTask>(); 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Save the default widget preview background 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Resources resources = context.getResources(); 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview_holo); 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mAppIconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size); 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0); 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mMaxAppCellCountX = a.getInt(R.styleable.AppsCustomizePagedView_maxAppCellCountX, -1); 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mMaxAppCellCountY = a.getInt(R.styleable.AppsCustomizePagedView_maxAppCellCountY, -1); 345b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta mWidgetWidthGap = 346b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellWidthGap, 0); 347b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta mWidgetHeightGap = 348b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellHeightGap, 0); 349b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2); 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2); 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mClingFocusedX = a.getInt(R.styleable.AppsCustomizePagedView_clingFocusedX, 0); 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mClingFocusedY = a.getInt(R.styleable.AppsCustomizePagedView_clingFocusedY, 0); 3532bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta a.recycle(); 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetSpacingLayout = new PagedViewCellLayout(getContext()); 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The padding on the non-matched dimension for the default widget preview icons 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (top + bottom) 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFadeInAdjacentScreens = false; 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Unless otherwise specified this view is important for accessibility. 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void init() { 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super.init(); 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCenterPagesVertically = false; 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Context context = getContext(); 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Resources r = context.getResources(); 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f); 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void onUnhandledTap(MotionEvent ev) { 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (LauncherApplication.isScreenLarge()) { 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Dismiss AppsCustomize if we tap 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.showWorkspace(true); 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Returns the item index of the center item on this page so that we can restore to this 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * item index when we rotate. */ 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int getMiddleComponentIndexOnCurrentPage() { 38737dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta int i = -1; 38837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta if (getPageCount() > 0) { 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int currentPage = getCurrentPage(); 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (currentPage < mNumAppsPages) { 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewCellLayout layout = (PagedViewCellLayout) getPageAt(currentPage); 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewCellLayoutChildren childrenLayout = layout.getChildrenLayout(); 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int numItemsPerPage = mCellCountX * mCellCountY; 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int childCount = childrenLayout.getChildCount(); 395bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta if (childCount > 0) { 396bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta i = (currentPage * numItemsPerPage) + (childCount / 2); 397bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta } 398bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta } else { 399bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta int numApps = mApps.size(); 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(currentPage); 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int numItemsPerPage = mWidgetCountX * mWidgetCountY; 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int childCount = layout.getChildCount(); 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (childCount > 0) { 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i = numApps + 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ((currentPage - mNumAppsPages) * numItemsPerPage) + (childCount / 2); 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 4079fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta } 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i; 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Get the index of the item to restore to if we need to restore the current page. */ 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int getSaveInstanceStateIndex() { 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mSaveInstanceStateItemIndex == -1) { 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSaveInstanceStateItemIndex = getMiddleComponentIndexOnCurrentPage(); 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mSaveInstanceStateItemIndex; 41891fa3ba4cc8acd4caeeb88f90ce39198b5fea414Diego Perez } 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Returns the page in the current orientation which is expected to contain the specified 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * item index. */ 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int getPageForComponent(int index) { 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) return 0; 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < mApps.size()) { 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int numItemsPerPage = mCellCountX * mCellCountY; 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (index / numItemsPerPage); 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int numItemsPerPage = mWidgetCountX * mWidgetCountY; 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mNumAppsPages + ((index - mApps.size()) / numItemsPerPage); 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Restores the page for an item at the specified index */ 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void restorePageForIndex(int index) { 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) return; 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSaveInstanceStateItemIndex = index; 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void updatePageCounts() { 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumWidgetPages = (int) Math.ceil(mWidgets.size() / 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (float) (mWidgetCountX * mWidgetCountY)); 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNumAppsPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY)); 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 445e91096c03dda225240b1487f019bf3d082854587Deepanshu Gupta 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void onDataReady(int width, int height) { 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note that we transpose the counts in portrait so that we get a similar layout 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean isLandscape = getResources().getConfiguration().orientation == 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Configuration.ORIENTATION_LANDSCAPE; 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxCellCountX = Integer.MAX_VALUE; 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxCellCountY = Integer.MAX_VALUE; 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (LauncherApplication.isScreenLarge()) { 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxCellCountX = (isLandscape ? LauncherModel.getCellCountX() : 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski LauncherModel.getCellCountY()); 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxCellCountY = (isLandscape ? LauncherModel.getCellCountY() : 45691fa3ba4cc8acd4caeeb88f90ce39198b5fea414Diego Perez LauncherModel.getCellCountX()); 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mMaxAppCellCountX > -1) { 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxCellCountX = Math.min(maxCellCountX, mMaxAppCellCountX); 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mMaxAppCellCountY > -1) { 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxCellCountY = Math.min(maxCellCountY, mMaxAppCellCountY); 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Now that the data is ready, we can calculate the content width, the number of cells to 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // use for each page 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetSpacingLayout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap); 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetSpacingLayout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPageLayoutPaddingRight, mPageLayoutPaddingBottom); 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetSpacingLayout.calculateCellCount(width, height, maxCellCountX, maxCellCountY); 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCellCountX = mWidgetSpacingLayout.getCellCountX(); 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCellCountY = mWidgetSpacingLayout.getCellCountY(); 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePageCounts(); 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Force a measure to update recalculate the gaps 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST); 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST); 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetSpacingLayout.measure(widthSpec, heightSpec); 47991fa3ba4cc8acd4caeeb88f90ce39198b5fea414Diego Perez mContentWidth = mWidgetSpacingLayout.getContentWidth(); 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppsCustomizeTabHost host = (AppsCustomizeTabHost) getTabHost(); 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final boolean hostIsTransitioning = host.isTransitioning(); 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Restore the page 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int page = getPageForComponent(mSaveInstanceStateItemIndex); 48637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta invalidatePageData(Math.max(0, page), hostIsTransitioning); 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 48837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta // Show All Apps cling if we are finished transitioning, otherwise, we will try again when 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the transition completes in AppsCustomizeTabHost (otherwise the wrong offsets will be 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // returned while animating) 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hostIsTransitioning) { 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski post(new Runnable() { 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run() { 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski showAllAppsCling(); 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }); 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void showAllAppsCling() { 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mHasShownAllAppsCling && isDataReady()) { 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mHasShownAllAppsCling = true; 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Calculate the position for the cling punch through 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] offset = new int[2]; 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] pos = mWidgetSpacingLayout.estimateCellPosition(mClingFocusedX, mClingFocusedY); 5076330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta mLauncher.getDragLayer().getLocationInDragLayer(this, offset); 5086330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta // PagedViews are centered horizontally but top aligned 5096330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta pos[0] += (getMeasuredWidth() - mWidgetSpacingLayout.getMeasuredWidth()) / 2 + 5106330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta offset[0]; 5116330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta pos[1] += offset[1]; 5126330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta mLauncher.showFirstRunAllAppsCling(pos); 5136330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta } 5146330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta } 5156330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta 5166330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta @Override 5176330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 5186330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta int width = MeasureSpec.getSize(widthMeasureSpec); 5196330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta int height = MeasureSpec.getSize(heightMeasureSpec); 5206330971ed293a2777bbdab09288f90ea4b2d0255Deepanshu Gupta if (!isDataReady()) { 521f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta if (!mApps.isEmpty() && !mWidgets.isEmpty()) { 522f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta setDataIsReady(); 523f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta setMeasuredDimension(width, height); 524f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta onDataReady(width, height); 525f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta } 526f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta } 527f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta 528f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta super.onMeasure(widthMeasureSpec, heightMeasureSpec); 529f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta } 530f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta 531f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta public void onPackagesUpdated() { 532f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta // TODO: this isn't ideal, but we actually need to delay here. This call is triggered 533f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta // by a broadcast receiver, and in order for it to work correctly, we need to know that 534f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta // the AppWidgetService has already received and processed the same broadcast. Since there 535f8ea750455eec81e4e6d877b3e18e29a86d4ec95Deepanshu Gupta // is no guarantee about ordering of broadcast receipt, we just delay here. This is a 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // workaround until we add a callback from AppWidgetService to AppWidgetHost when widget 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // packages are added, updated or removed. 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski postDelayed(new Runnable() { 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run() { 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePackages(); 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }, 1500); 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void updatePackages() { 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Get the list of widgets and shortcuts 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgets.clear(); 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski List<AppWidgetProviderInfo> widgets = 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppWidgetManager.getInstance(mLauncher).getInstalledProviders(); 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski List<ResolveInfo> shortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0); 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (AppWidgetProviderInfo widget : widgets) { 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (widget.minWidth > 0 && widget.minHeight > 0) { 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Ensure that all widgets we show can be added on a workspace of this size 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget); 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget); 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int minSpanX = Math.min(spanXY[0], minSpanXY[0]); 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int minSpanY = Math.min(spanXY[1], minSpanXY[1]); 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (minSpanX <= LauncherModel.getCellCountX() && 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski minSpanY <= LauncherModel.getCellCountY()) { 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgets.add(widget); 562664d6f1fe4d6dfa742b3e98051f924dbc190f8caDeepanshu Gupta } else { 563664d6f1fe4d6dfa742b3e98051f924dbc190f8caDeepanshu Gupta Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" + 564664d6f1fe4d6dfa742b3e98051f924dbc190f8caDeepanshu Gupta widget.minWidth + ", " + widget.minHeight + ")"); 565664d6f1fe4d6dfa742b3e98051f924dbc190f8caDeepanshu Gupta } 566e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta } else { 567e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" + 568e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta widget.minWidth + ", " + widget.minHeight + ")"); 569e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta } 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgets.addAll(shortcuts); 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Collections.sort(mWidgets, 5736e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager)); 5746e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown updatePageCounts(); 5756e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown invalidateOnDataChange(); 5766e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown } 5776e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown 5786e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown @Override 5796e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown public void onClick(View v) { 5806e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown // When we have exited all apps or are in transition, disregard clicks 5816e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown if (!mLauncher.isAllAppsCustomizeOpen() || 5826e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown mLauncher.getWorkspace().isSwitchingState()) return; 5836e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown 5846e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown if (v instanceof PagedViewIcon) { 5856e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown // Animate some feedback to the click 5866e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown final ApplicationInfo appInfo = (ApplicationInfo) v.getTag(); 5876e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown 5886e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown // Lock the drawable state to pressed until we return to Launcher 5896e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown if (mPressedIcon != null) { 5906e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown mPressedIcon.lockDrawableState(); 5916e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown } 5926e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown 5936e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown // NOTE: We want all transitions from launcher to act as if the wallpaper were enabled 5946e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown // to be consistent. So re-enable the flag here, and we will re-disable it as necessary 5956e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown // when Launcher resumes and we are still in AllApps. 5966e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown mLauncher.updateWallpaperVisibility(true); 5976e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown mLauncher.startActivitySafely(v, appInfo.intent, appInfo); 5986e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown 5996e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown } else if (v instanceof PagedViewWidget) { 6006e53931f49f49245deef8622eb8e7dc6ccf04536Jeff Brown // Let the user know that they have to long press to add a widget 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Toast.makeText(getContext(), R.string.long_press_widget_to_add, 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Toast.LENGTH_SHORT).show(); 6034a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta 60491253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta // Create a little animation to show that the widget can move 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float offsetY = getResources().getDimensionPixelSize(R.dimen.dragViewOffsetY); 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final ImageView p = (ImageView) v.findViewById(R.id.widget_preview); 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AnimatorSet bounce = new AnimatorSet(); 60891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta ValueAnimator tyuAnim = ObjectAnimator.ofFloat(p, "translationY", offsetY); 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tyuAnim.setDuration(125); 610e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta ValueAnimator tydAnim = ObjectAnimator.ofFloat(p, "translationY", 0f); 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tydAnim.setDuration(100); 61291253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta bounce.play(tyuAnim).before(tydAnim); 61391253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta bounce.setInterpolator(new AccelerateInterpolator()); 614e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta bounce.start(); 615e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta } 616e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta } 61791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 618e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta public boolean onKey(View v, int keyCode, KeyEvent event) { 619e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta return FocusHelper.handleAppsCustomizeKeyEvent(v, keyCode, event); 620e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta } 6218657baa06d2efe845cafef571bd9dce627cf5045Deepanshu Gupta 6228657baa06d2efe845cafef571bd9dce627cf5045Deepanshu Gupta /* 623e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta * PagedViewWithDraggableItems implementation 624e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta */ 625e64a5bd2fb54d84d6fd2119ef831df1eba4185ffDeepanshu Gupta @Override 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void determineDraggingStart(android.view.MotionEvent ev) { 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Disable dragging by pulling an app down for now. 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 62991253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void beginDraggingApplication(View v) { 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.getWorkspace().onDragStartedWithItem(v); 632eb26f5cecd5366b29b3cb746a7edaf3769f40480Deepanshu Gupta mLauncher.getWorkspace().beginDragShared(v, this); 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 63491253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 63591253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta private void preloadWidget(final PendingAddWidgetInfo info) { 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final AppWidgetProviderInfo pInfo = info.info; 63791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta if (pInfo.configure != null) { 63891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta return; 63991253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 64191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta mWidgetCleanupState = WIDGET_PRELOAD_PENDING; 64291253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta mBindWidgetRunnable = new Runnable() { 6438cdf61a02e4652d53560c9758b8b15e76c50bfd7Diego Perez @Override 6448cdf61a02e4652d53560c9758b8b15e76c50bfd7Diego Perez public void run() { 64591253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId(); 64691253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta if (AppWidgetManager.getInstance(mLauncher) 64791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta .bindAppWidgetIdIfAllowed(mWidgetLoadingId, info.componentName)) { 64891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta mWidgetCleanupState = WIDGET_BOUND; 64991253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 65091253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 65191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta }; 65291253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta post(mBindWidgetRunnable); 65391253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 65491253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta mInflateWidgetRunnable = new Runnable() { 65591253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta @Override 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run() { 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppWidgetHostView hostView = mLauncher. 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getAppWidgetHost().createView(getContext(), mWidgetLoadingId, pInfo); 6594a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta info.boundWidget = hostView; 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetCleanupState = WIDGET_INFLATED; 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hostView.setVisibility(INVISIBLE); 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(info.spanX, 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski info.spanY, info, false); 6644a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We want the first widget layout to be the correct size. This will be important 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // for width size reporting to the AppWidgetManager. 66791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta DragLayer.LayoutParams lp = new DragLayer.LayoutParams(unScaledSize[0], 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unScaledSize[1]); 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lp.x = lp.y = 0; 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lp.customPosition = true; 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hostView.setLayoutParams(lp); 67285d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta mLauncher.getDragLayer().addView(hostView); 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }; 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski post(mInflateWidgetRunnable); 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void onShortPress(View v) { 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We are anticipating a long press, and we use this time to load bind and instantiate 68191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta // the widget. This will need to be cleaned up if it turns out no long press occurs. 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCreateWidgetInfo != null) { 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Just in case the cleanup process wasn't properly executed. This shouldn't happen. 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cleanupWidgetPreloading(false); 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCreateWidgetInfo = new PendingAddWidgetInfo((PendingAddWidgetInfo) v.getTag()); 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski preloadWidget(mCreateWidgetInfo); 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void cleanupWidgetPreloading(boolean widgetWasAdded) { 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!widgetWasAdded) { 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the widget was not added, we may need to do further cleanup. 69385d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta PendingAddWidgetInfo info = mCreateWidgetInfo; 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCreateWidgetInfo = null; 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mWidgetCleanupState == WIDGET_PRELOAD_PENDING) { 697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We never did any preloading, so just remove pending callbacks to do so 698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski removeCallbacks(mBindWidgetRunnable); 699e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta removeCallbacks(mInflateWidgetRunnable); 700e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta } else if (mWidgetCleanupState == WIDGET_BOUND) { 701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Delete the widget id which was allocated 702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mWidgetLoadingId != -1) { 703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId); 704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 70585d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta 706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We never got around to inflating the widget, so remove the callback to do so. 707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski removeCallbacks(mInflateWidgetRunnable); 708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (mWidgetCleanupState == WIDGET_INFLATED) { 709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Delete the widget id which was allocated 710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mWidgetLoadingId != -1) { 711fba1dd24bf7b56071490ac62428f96d14f682244Deepanshu Gupta mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId); 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The widget was inflated and added to the DragLayer -- remove it. 715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppWidgetHostView widget = info.boundWidget; 716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.getDragLayer().removeView(widget); 717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED; 720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetLoadingId = -1; 721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCreateWidgetInfo = null; 722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewWidget.resetShortPressTarget(); 723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void cleanUpShortPress(View v) { 727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mDraggingWidget) { 72885d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta cleanupWidgetPreloading(false); 72985d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta } 73085d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta } 73185d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta 73285d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta private boolean beginDraggingWidget(View v) { 73385d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta mDraggingWidget = true; 73485d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta // Get the widget preview as the drag representation 73579c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta ImageView image = (ImageView) v.findViewById(R.id.widget_preview); 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag(); 73785d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta 73879c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and 73985d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta // we abort the drag. 740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (image.getDrawable() == null) { 74185d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta mDraggingWidget = false; 74285d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta return false; 74385d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta } 7445d1eaf4a197130f561b16c4ed083cf016b20ab92Deepanshu Gupta 74585d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta // Compose the drag image 74685d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta Bitmap preview; 74785d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta Bitmap outline; 74879c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta float scale = 1f; 74979c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta if (createItemInfo instanceof PendingAddWidgetInfo) { 75079c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta // This can happen in some weird cases involving multi-touch. We can't start dragging 75179c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta // the widget if this is null, so we break out. 75279c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta if (mCreateWidgetInfo == null) { 75379c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta return false; 75485d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta } 75585d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta 75685d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta PendingAddWidgetInfo createWidgetInfo = mCreateWidgetInfo; 75785d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta createItemInfo = createWidgetInfo; 75885d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta int spanX = createItemInfo.spanX; 75985d72c4535003af3b9df77bd6eaa2b33e8a7cba2Deepanshu Gupta int spanY = createItemInfo.spanY; 760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] size = mLauncher.getWorkspace().estimateItemSize(spanX, spanY, 761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createWidgetInfo, true); 762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 763d758e042ce08c46712db3db2d63fc84795028dfeDeepanshu Gupta FastBitmapDrawable previewDrawable = (FastBitmapDrawable) image.getDrawable(); 764d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta float minScale = 1.25f; 765d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta int maxWidth, maxHeight; 766d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta maxWidth = Math.min((int) (previewDrawable.getIntrinsicWidth() * minScale), size[0]); 767d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta maxHeight = Math.min((int) (previewDrawable.getIntrinsicHeight() * minScale), size[1]); 768d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta preview = getWidgetPreview(createWidgetInfo.componentName, createWidgetInfo.previewImage, 769d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta createWidgetInfo.icon, spanX, spanY, maxWidth, maxHeight); 770d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta 771d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // Determine the image view drawable scale relative to the preview 772d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta float[] mv = new float[9]; 773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Matrix m = new Matrix(); 774d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta m.setRectToRect( 775d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta new RectF(0f, 0f, (float) preview.getWidth(), (float) preview.getHeight()), 776d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta new RectF(0f, 0f, (float) previewDrawable.getIntrinsicWidth(), 777d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta (float) previewDrawable.getIntrinsicHeight()), 778d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta Matrix.ScaleToFit.START); 779d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta m.getValues(mv); 78079c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta scale = (float) mv[0]; 78179c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta } else { 782d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag(); 783d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.shortcutActivityInfo); 784d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta preview = Bitmap.createBitmap(icon.getIntrinsicWidth(), 785d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); 786d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta 787d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta mCanvas.setBitmap(preview); 788d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta mCanvas.save(); 789d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta renderDrawableToBitmap(icon, preview, 0, 0, 790d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); 791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCanvas.restore(); 792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCanvas.setBitmap(null); 793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createItemInfo.spanX = createItemInfo.spanY = 1; 794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 795d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta 796d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // We use a custom alpha clip table for the default widget previews 7974f8ce228195be123eeb9b5f066a6abc92b8d923aDeepanshu Gupta Paint alphaClipPaint = null; 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (createItemInfo instanceof PendingAddWidgetInfo) { 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (((PendingAddWidgetInfo) createItemInfo).previewImage != 0) { 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MaskFilter alphaClipTable = TableMaskFilter.CreateClipTable(0, 255); 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski alphaClipPaint = new Paint(); 802d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta alphaClipPaint.setMaskFilter(alphaClipTable); 803d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 8044f8ce228195be123eeb9b5f066a6abc92b8d923aDeepanshu Gupta } 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Save the preview for the outline generation, then dim the preview 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outline = Bitmap.createScaledBitmap(preview, preview.getWidth(), preview.getHeight(), 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski false); 80937dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta 810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Start the drag 811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski alphaClipPaint = null; 812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.lockScreenOrientation(); 813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, outline, alphaClipPaint); 814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDragController.startDrag(image, preview, this, createItemInfo, 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski DragController.DRAG_ACTION_COPY, null, scale); 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski outline.recycle(); 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski preview.recycle(); 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 8209fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected boolean beginDragging(final View v) { 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!super.beginDragging(v)) return false; 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v instanceof PagedViewIcon) { 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski beginDraggingApplication(v); 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (v instanceof PagedViewWidget) { 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!beginDraggingWidget(v)) { 8299fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta return false; 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We delay entering spring-loaded mode slightly to make sure the UI 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // thready is free of any work. 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski postDelayed(new Runnable() { 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run() { 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We don't enter spring-loaded mode if the drag has been cancelled 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mLauncher.getDragController().isDragging()) { 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Dismiss the cling 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.dismissAllAppsCling(null); 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Reset the alpha on the dragged icon before we drag 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resetDrawableState(); 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Go into spring loaded mode (must happen before we startDrag()) 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher.enterSpringLoadedDragMode(); 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }, 150); 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Clean up after dragging. 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param target where the item was dragged to (can be null if the item was flung) 859282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 86079c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta private void endDragging(View target, boolean isFlingToDelete, boolean success) { 86179c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() && 86279c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta !(target instanceof DeleteDropTarget))) { 863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Exit spring loaded mode if we have not successfully dropped or have not handled the 864a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta // drop in Workspace 865a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta mLauncher.exitSpringLoadedDragMode(); 866a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta } 86779c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta mLauncher.unlockScreenOrientation(false); 868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 870b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta @Override 871b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta public View getContent() { 872b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta return null; 873b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta } 874b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta 875b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta @Override 876b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) { 877b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta mInTransition = true; 878b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta if (toWorkspace) { 879b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta cancelAllTasks(); 880b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta } 881b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta } 882b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta 883b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta @Override 884b3e872be9e634c8d1f34d07778ea753880bbf2d9Deepanshu Gupta public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) { 885282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 886282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 887282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void onLauncherTransitionStep(Launcher l, float t) { 889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 892282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) { 893282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mInTransition = false; 894282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (AsyncTaskPageData d : mDeferredSyncWidgetPageItems) { 895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onSyncWidgetPageItems(d); 896282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDeferredSyncWidgetPageItems.clear(); 898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Runnable r : mDeferredPrepareLoadWidgetPreviewsTasks) { 899282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski r.run(); 900282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 901282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDeferredPrepareLoadWidgetPreviewsTasks.clear(); 902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mForceDrawAllChildrenNextFrame = !toWorkspace; 903282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 904282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete, 907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean success) { 9082bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta // Return early and wait for onFlingToDeleteCompleted if this was the result of a fling 9092bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta if (isFlingToDelete) return; 9102bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta 9112bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta endDragging(target, false, success); 9122bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta 9132bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta // Display an error message if the drag failed due to there not being enough space on the 9142bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta // target layout we were dropping on. 9152bc2daa74eef01135f717eadfab87538a9bef29fDeepanshu Gupta if (!success) { 916490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta boolean showOutOfSpaceMessage = false; 917490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta if (target instanceof Workspace) { 918490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta int currentScreen = mLauncher.getCurrentWorkspaceScreen(); 919490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta Workspace workspace = (Workspace) target; 920490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen); 921490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta ItemInfo itemInfo = (ItemInfo) d.dragInfo; 922490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta if (layout != null) { 923490dd90c707de8426a068a90d74ec83c9c11fc83Deepanshu Gupta layout.calculateSpans(itemInfo); 924282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski showOutOfSpaceMessage = 925282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY); 926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 927282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 928bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta if (showOutOfSpaceMessage) { 929bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta mLauncher.showOutOfSpaceMessage(false); 930bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta } 931282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 932282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.deferDragViewCleanupPostAnimation = false; 93391253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 93491253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta cleanupWidgetPreloading(success); 935282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDraggingWidget = false; 936282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 937a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta 938a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta @Override 939282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void onFlingToDeleteCompleted() { 94091253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta // We just dismiss the drag when we fling, so cleanup here 941282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski endDragging(null, true, true); 94291253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta cleanupWidgetPreloading(false); 943282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDraggingWidget = false; 944282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 945282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 946282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 947bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta public boolean supportsFlingToDelete() { 94891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta return true; 949a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta } 950bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta 951a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta @Override 952bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta protected void onDetachedFromWindow() { 953a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta super.onDetachedFromWindow(); 954bfec73c2db5a34ced248213edf5519c80727a65fDeepanshu Gupta cancelAllTasks(); 955282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 956282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 95791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta public void clearAllWidgetPages() { 95879c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta cancelAllTasks(); 959282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = getChildCount(); 96079c59fe4a8544bdda5c56efecf9c2bc72f2f0e4eDeepanshu Gupta for (int i = 0; i < count; i++) { 961a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta View v = getPageAt(i); 962a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta if (v instanceof PagedViewGridLayout) { 963a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta ((PagedViewGridLayout) v).removeAllViewsOnPage(); 964a43c4fa09ff758400c17c3533b77d783e713a115Deepanshu Gupta mDirtyPageContent.set(i, true); 965282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 966282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 967282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 968282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 969282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void cancelAllTasks() { 970282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Clean up all the async tasks 97191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 972282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (iter.hasNext()) { 973282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 974282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski task.cancel(false); 975282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski iter.remove(); 976282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDirtyPageContent.set(task.page, true); 977282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 978282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We've already preallocated the views for the data to load into, so clear them as well 979282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski View v = getPageAt(task.page); 980282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v instanceof PagedViewGridLayout) { 981282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ((PagedViewGridLayout) v).removeAllViewsOnPage(); 982282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 98391253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 984282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDeferredSyncWidgetPageItems.clear(); 985282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDeferredPrepareLoadWidgetPreviewsTasks.clear(); 9869fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta } 9879fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta 988282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void setContentType(ContentType type) { 989282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (type == ContentType.Widgets) { 990282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski invalidatePageData(mNumAppsPages, true); 991282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (type == ContentType.Applications) { 99237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta invalidatePageData(0, true); 993282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 994282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 995282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 996282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void snapToPage(int whichPage, int delta, int duration) { 997282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super.snapToPage(whichPage, delta, duration); 998282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updateCurrentTab(whichPage); 999282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1000282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update the thread priorities given the direction lookahead 1001282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 1002282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (iter.hasNext()) { 1003282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 1004282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pageIndex = task.page; 1005282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if ((mNextPage > mCurrentPage && pageIndex >= mCurrentPage) || 1006282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (mNextPage < mCurrentPage && pageIndex <= mCurrentPage)) { 1007282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski task.setThreadPriority(getThreadPriorityForPage(pageIndex)); 1008282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1009282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski task.setThreadPriority(Process.THREAD_PRIORITY_LOWEST); 1010282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1011282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 101291253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 1013282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1014282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void updateCurrentTab(int currentPage) { 1015282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppsCustomizeTabHost tabHost = getTabHost(); 1016282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tabHost != null) { 1017282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String tag = tabHost.getCurrentTabTag(); 101837dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta if (tag != null) { 1019282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (currentPage >= mNumAppsPages && 1020282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !tag.equals(tabHost.getTabTagForContentType(ContentType.Widgets))) { 1021282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tabHost.setCurrentTabFromContent(ContentType.Widgets); 1022282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (currentPage < mNumAppsPages && 1023282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski !tag.equals(tabHost.getTabTagForContentType(ContentType.Applications))) { 1024282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tabHost.setCurrentTabFromContent(ContentType.Applications); 1025282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1026282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1027282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1028282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 102991253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 103091253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta /* 1031282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Apps PagedView implementation 1032282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1033282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void setVisibilityOnChildren(ViewGroup layout, int visibility) { 1034282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int childCount = layout.getChildCount(); 1035282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < childCount; ++i) { 1036282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.getChildAt(i).setVisibility(visibility); 1037282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 10389fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta } 1039282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void setupPage(PagedViewCellLayout layout) { 1040282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.setCellCount(mCellCountX, mCellCountY); 1041282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap); 1042282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, 1043282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPageLayoutPaddingRight, mPageLayoutPaddingBottom); 1044282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1045282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Note: We force a measure here to get around the fact that when we do layout calculations 1046282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // immediately after syncing, we don't have a proper width. That said, we already know the 1047282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // expected page width, so we can actually optimize by hiding all the TextView-based 1048282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // children that are expensive to measure, and let that happen naturally later. 1049282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setVisibilityOnChildren(layout, View.GONE); 1050282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST); 1051282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST); 1052282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.setMinimumWidth(getPageContentWidth()); 1053282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.measure(widthSpec, heightSpec); 1054282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski setVisibilityOnChildren(layout, View.VISIBLE); 1055282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1056282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 10579fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta public void syncAppsPageItems(int page, boolean immediate) { 10589fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta // ensure that we have the right number of items on the pages 10599fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta int numCells = mCellCountX * mCellCountY; 10609fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta int startIndex = page * numCells; 1061282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int endIndex = Math.min(startIndex + numCells, mApps.size()); 1062282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewCellLayout layout = (PagedViewCellLayout) getPageAt(page); 1063282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1064282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.removeAllViewsOnPage(); 1065282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<Object> items = new ArrayList<Object>(); 1066282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<Bitmap> images = new ArrayList<Bitmap>(); 10679fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta for (int i = startIndex; i < endIndex; ++i) { 10689fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta ApplicationInfo info = mApps.get(i); 10699fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta PagedViewIcon icon = (PagedViewIcon) mLayoutInflater.inflate( 107037dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta R.layout.apps_customize_application, layout, false); 107137dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta icon.applyFromApplicationInfo(info, true, this); 10729fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta icon.setOnClickListener(this); 10739fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta icon.setOnLongClickListener(this); 10749fa48b09ad06c39be0923d5ca64b81f6b0eee993Deepanshu Gupta icon.setOnTouchListener(this); 1075282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski icon.setOnKeyListener(this); 1076282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1077282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int index = i - startIndex; 1078282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int x = index % mCellCountX; 1079282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int y = index / mCellCountX; 1080282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1)); 1081ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Gupta 1082ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Gupta items.add(info); 1083ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Gupta images.add(info.iconBitmap); 1084ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Gupta } 1085ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Gupta 1086ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Gupta layout.createHardwareLayers(); 1087ada8590547348b77d8cbd56abdb8fadb3e72c015Deepanshu Gupta } 1088d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta 1089d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta /** 1090d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta * A helper to return the priority for loading of the specified widget page. 1091d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta */ 1092d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta private int getWidgetPageLoadPriority(int page) { 1093d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // If we are snapping to another page, use that index as the target page index 1094d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta int toPage = mCurrentPage; 1095d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta if (mNextPage > -1) { 1096d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta toPage = mNextPage; 1097d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 1098d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta 1099d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // We use the distance from the target page as an initial guess of priority, but if there 1100d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // are no pages of higher priority than the page specified, then bump up the priority of 1101d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // the specified page. 1102d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 1103d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta int minPageDiff = Integer.MAX_VALUE; 1104d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta while (iter.hasNext()) { 1105d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 1106d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta minPageDiff = Math.abs(task.page - toPage); 1107d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 1108d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta 1109d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta int rawPageDiff = Math.abs(page - toPage); 1110d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta return rawPageDiff - Math.min(rawPageDiff, minPageDiff); 1111d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 1112d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta /** 1113d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta * Return the appropriate thread priority for loading for a given page (we give the current 1114d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta * page much higher priority) 1115d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta */ 1116d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta private int getThreadPriorityForPage(int page) { 1117d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // TODO-APPS_CUSTOMIZE: detect number of cores and set thread priorities accordingly below 1118d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta int pageDiff = getWidgetPageLoadPriority(page); 1119d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta if (pageDiff <= 0) { 1120d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta return Process.THREAD_PRIORITY_LESS_FAVORABLE; 1121d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } else if (pageDiff <= 1) { 1122d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta return Process.THREAD_PRIORITY_LOWEST; 1123d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } else { 1124d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta return Process.THREAD_PRIORITY_LOWEST; 1125d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 1126d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 1127d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta private int getSleepForPage(int page) { 1128d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta int pageDiff = getWidgetPageLoadPriority(page); 1129d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta return Math.max(0, pageDiff * sPageSleepDelay); 1130d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } 1131d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta /** 1132d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta * Creates and executes a new AsyncTask to load a page of widget previews. 1133d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta */ 1134d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta private void prepareLoadWidgetPreviewsTask(int page, ArrayList<Object> widgets, 1135d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta int cellWidth, int cellHeight, int cellCountX) { 1136d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta 1137d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta // Prune all tasks that are no longer needed 1138e8a04cd5a68a5e5aa78a4f40b3269c86cc3f152fIan Pedowitz Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 1139e8a04cd5a68a5e5aa78a4f40b3269c86cc3f152fIan Pedowitz while (iter.hasNext()) { 1140e8a04cd5a68a5e5aa78a4f40b3269c86cc3f152fIan Pedowitz AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 1141e8a04cd5a68a5e5aa78a4f40b3269c86cc3f152fIan Pedowitz int taskPage = task.page; 1142e8a04cd5a68a5e5aa78a4f40b3269c86cc3f152fIan Pedowitz if (taskPage < getAssociatedLowerPageBound(mCurrentPage) || 1143d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta taskPage > getAssociatedUpperPageBound(mCurrentPage)) { 1144d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta task.cancel(false); 1145d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta iter.remove(); 1146d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta } else { 1147d5b82845450beac2d3c7db9cd80e9fc34d43a297Deepanshu Gupta task.setThreadPriority(getThreadPriorityForPage(taskPage)); 1148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We introduce a slight delay to order the loading of side pages so that we don't thrash 1152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int sleepMs = getSleepForPage(page); 1153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskPageData pageData = new AsyncTaskPageData(page, widgets, cellWidth, cellHeight, 1154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new AsyncTaskCallback() { 1155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) { 1157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 1158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 1159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Thread.sleep(sleepMs); 1160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (Exception e) {} 1161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski loadWidgetPreviewsInBackground(task, data); 1162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } finally { 1163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (task.isCancelled()) { 1164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski data.cleanup(true); 1165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }, 1169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new AsyncTaskCallback() { 1170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) { 1172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mRunningTasks.remove(task); 1173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (task.isCancelled()) return; 1174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // do cleanup inside onSyncWidgetPageItems 1175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onSyncWidgetPageItems(data); 1176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }); 1178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Ensure that the task is appropriately prioritized and runs in parallel 1180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page, 1181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskPageData.Type.LoadWidgetPreviewData); 1182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t.setThreadPriority(getThreadPriorityForPage(page)); 1183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pageData); 1184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mRunningTasks.add(t); 1185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1187c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav /* 1188c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav * Widgets PagedView implementation 1189c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav */ 1190c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav private void setupPage(PagedViewGridLayout layout) { 1191c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, 1192c6d1c345f41cf817bf2c07c97b97107d94296064Svetoslav mPageLayoutPaddingRight, mPageLayoutPaddingBottom); 1193ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn 1194ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn // Note: We force a measure here to get around the fact that when we do layout calculations 1195ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn // immediately after syncing, we don't have a proper width. 1196ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST); 1197ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST); 1198ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn layout.setMinimumWidth(getPageContentWidth()); 1199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.measure(widthSpec, heightSpec); 1200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) { 1203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski renderDrawableToBitmap(d, bitmap, x, y, w, h, 1f); 1204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1205ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn 1206ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h, 1207ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn float scale) { 1208ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn if (bitmap != null) { 1209ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn Canvas c = new Canvas(bitmap); 1210ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn c.scale(scale, scale); 1211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Rect oldBounds = d.copyBounds(); 1212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.setBounds(x, y, x + w, y + h); 1213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.draw(c); 1214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski d.setBounds(oldBounds); // Restore the bounds 1215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(null); 1216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Bitmap getShortcutPreview(ResolveInfo info, int maxWidth, int maxHeight) { 1220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap tempBitmap = mCachedShortcutPreviewBitmap.get(); 1221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Canvas c = mCachedShortcutPreviewCanvas.get(); 1222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tempBitmap == null || 1223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tempBitmap.getWidth() != maxWidth || 1224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tempBitmap.getHeight() != maxHeight) { 1225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tempBitmap = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888); 1226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCachedShortcutPreviewBitmap.set(tempBitmap); 1227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(tempBitmap); 1229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.drawColor(0, PorterDuff.Mode.CLEAR); 1230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(null); 1231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Render the icon 1233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Drawable icon = mIconCache.getFullResIcon(info); 1234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int paddingTop = 1236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top); 1237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int paddingLeft = 1238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_left); 1239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int paddingRight = 1240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_right); 1241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int scaledIconWidth = (maxWidth - paddingLeft - paddingRight); 1243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float scaleSize = scaledIconWidth / (float) mAppIconSize; 1244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski renderDrawableToBitmap( 1246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski icon, tempBitmap, paddingLeft, paddingTop, scaledIconWidth, scaledIconWidth); 1247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888); 1249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(preview); 1250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Paint p = mCachedShortcutPreviewPaint.get(); 1251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == null) { 1252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = new Paint(); 1253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ColorMatrix colorMatrix = new ColorMatrix(); 12544f6a6c48a4e6b9f6e4ced3d10bb51db5d2c22eadSvetoslav colorMatrix.setSaturation(0); 12554f6a6c48a4e6b9f6e4ced3d10bb51db5d2c22eadSvetoslav p.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); 12564f6a6c48a4e6b9f6e4ced3d10bb51db5d2c22eadSvetoslav p.setAlpha((int) (255 * 0.06f)); 12574f6a6c48a4e6b9f6e4ced3d10bb51db5d2c22eadSvetoslav //float density = 1f; 12584f6a6c48a4e6b9f6e4ced3d10bb51db5d2c22eadSvetoslav //p.setMaskFilter(new BlurMaskFilter(15*density, BlurMaskFilter.Blur.NORMAL)); 12594f6a6c48a4e6b9f6e4ced3d10bb51db5d2c22eadSvetoslav mCachedShortcutPreviewPaint.set(p); 12608a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey } 126135871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey c.drawBitmap(tempBitmap, 0, 0, p); 126235871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey c.setBitmap(null); 126335871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey 126435871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey renderDrawableToBitmap(icon, preview, 0, 0, mAppIconSize, mAppIconSize); 126535871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey 1266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return preview; 1267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Bitmap getWidgetPreview(ComponentName provider, int previewImage, 1270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int iconId, int cellHSpan, int cellVSpan, int maxWidth, 1271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxHeight) { 1272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load the preview image if possible 1273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String packageName = provider.getPackageName(); 1274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (maxWidth < 0) maxWidth = Integer.MAX_VALUE; 1275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (maxHeight < 0) maxHeight = Integer.MAX_VALUE; 1276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Drawable drawable = null; 1278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (previewImage != 0) { 1279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski drawable = mPackageManager.getDrawable(packageName, previewImage, null); 1280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (drawable == null) { 1281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Log.w(TAG, "Can't load widget preview drawable 0x" + 1282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Integer.toHexString(previewImage) + " for provider: " + provider); 1283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int bitmapWidth; 1287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int bitmapHeight; 1288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap defaultPreview = null; 1289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean widgetPreviewExists = (drawable != null); 1290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (widgetPreviewExists) { 1291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bitmapWidth = drawable.getIntrinsicWidth(); 1292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bitmapHeight = drawable.getIntrinsicHeight(); 1293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Generate a preview image if we couldn't load one 1295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cellHSpan < 1) cellHSpan = 1; 1296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (cellVSpan < 1) cellVSpan = 1; 1297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski BitmapDrawable previewDrawable = (BitmapDrawable) getResources() 1299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .getDrawable(R.drawable.widget_preview_tile); 1300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int previewDrawableWidth = previewDrawable 1301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .getIntrinsicWidth(); 1302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int previewDrawableHeight = previewDrawable 1303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski .getIntrinsicHeight(); 1304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bitmapWidth = previewDrawableWidth * cellHSpan; // subtract 2 dips 1305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bitmapHeight = previewDrawableHeight * cellVSpan; 1306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski defaultPreview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, 1308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Config.ARGB_8888); 1309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Canvas c = mCachedAppWidgetPreviewCanvas.get(); 1310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(defaultPreview); 1311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski previewDrawable.setBounds(0, 0, bitmapWidth, bitmapHeight); 1312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski previewDrawable.setTileModeXY(Shader.TileMode.REPEAT, 1313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Shader.TileMode.REPEAT); 1314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski previewDrawable.draw(c); 1315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(null); 1316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Draw the icon in the top left corner 1318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int minOffset = (int) (mAppIconSize * sWidgetPreviewIconPaddingPercentage); 1319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int smallestSide = Math.min(bitmapWidth, bitmapHeight); 1320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float iconScale = Math.min((float) smallestSide 1321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski / (mAppIconSize + 2 * minOffset), 1f); 1322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 1324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Drawable icon = null; 1325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int hoffset = 1326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (int) ((previewDrawableWidth - mAppIconSize * iconScale) / 2); 1327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int yoffset = 1328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (int) ((previewDrawableHeight - mAppIconSize * iconScale) / 2); 1329d51834bdfad0cd3142ac464ab3a3b0db14f884c3Deepanshu Gupta if (iconId > 0) 1330d51834bdfad0cd3142ac464ab3a3b0db14f884c3Deepanshu Gupta icon = mIconCache.getFullResIcon(packageName, iconId); 1331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Resources resources = mLauncher.getResources(); 1332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (icon != null) { 1333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski renderDrawableToBitmap(icon, defaultPreview, hoffset, 1334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski yoffset, (int) (mAppIconSize * iconScale), 1335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski (int) (mAppIconSize * iconScale)); 1336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (Resources.NotFoundException e) { 1338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 13404ed745d359ada6986ac15d8718452e5c55f40170Jeff Sharkey 13414ed745d359ada6986ac15d8718452e5c55f40170Jeff Sharkey // Scale to fit width only - let the widget preview be clipped in the 13424ed745d359ada6986ac15d8718452e5c55f40170Jeff Sharkey // vertical dimension 13434ed745d359ada6986ac15d8718452e5c55f40170Jeff Sharkey float scale = 1f; 13444ed745d359ada6986ac15d8718452e5c55f40170Jeff Sharkey if (bitmapWidth > maxWidth) { 13454ed745d359ada6986ac15d8718452e5c55f40170Jeff Sharkey scale = maxWidth / (float) bitmapWidth; 1346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (scale != 1f) { 1348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bitmapWidth = (int) (scale * bitmapWidth); 1349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bitmapHeight = (int) (scale * bitmapHeight); 1350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, 1353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Config.ARGB_8888); 1354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Draw the scaled preview into the final bitmap 1356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (widgetPreviewExists) { 1357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski renderDrawableToBitmap(drawable, preview, 0, 0, bitmapWidth, 1358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bitmapHeight); 1359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Canvas c = mCachedAppWidgetPreviewCanvas.get(); 1361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Rect src = mCachedAppWidgetPreviewSrcRect.get(); 1362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final Rect dest = mCachedAppWidgetPreviewDestRect.get(); 1363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(preview); 1364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski src.set(0, 0, defaultPreview.getWidth(), defaultPreview.getHeight()); 1365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dest.set(0, 0, preview.getWidth(), preview.getHeight()); 1366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Paint p = mCachedAppWidgetPreviewPaint.get(); 1368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (p == null) { 1369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p = new Paint(); 1370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski p.setFilterBitmap(true); 1371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCachedAppWidgetPreviewPaint.set(p); 1372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.drawBitmap(defaultPreview, src, dest, p); 1374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c.setBitmap(null); 1375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return preview; 1377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 13786a6cdafaec56fcd793214678c7fcc52f0b860cfcJeff Sharkey 13796a6cdafaec56fcd793214678c7fcc52f0b860cfcJeff Sharkey public void syncWidgetPageItems(final int page, final boolean immediate) { 13806a6cdafaec56fcd793214678c7fcc52f0b860cfcJeff Sharkey int numItemsPerPage = mWidgetCountX * mWidgetCountY; 13816a6cdafaec56fcd793214678c7fcc52f0b860cfcJeff Sharkey 13826a6cdafaec56fcd793214678c7fcc52f0b860cfcJeff Sharkey // Calculate the dimensions of each cell we are giving to each widget 13836a6cdafaec56fcd793214678c7fcc52f0b860cfcJeff Sharkey final ArrayList<Object> items = new ArrayList<Object>(); 13842c1ba9a961d4f96c26df260ee437655ad9e7c03eJeff Sharkey int contentWidth = mWidgetSpacingLayout.getContentWidth(); 13852c1ba9a961d4f96c26df260ee437655ad9e7c03eJeff Sharkey final int cellWidth = ((contentWidth - mPageLayoutPaddingLeft - mPageLayoutPaddingRight 13862c1ba9a961d4f96c26df260ee437655ad9e7c03eJeff Sharkey - ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX); 13872c1ba9a961d4f96c26df260ee437655ad9e7c03eJeff Sharkey int contentHeight = mWidgetSpacingLayout.getContentHeight(); 13882c1ba9a961d4f96c26df260ee437655ad9e7c03eJeff Sharkey final int cellHeight = ((contentHeight - mPageLayoutPaddingTop - mPageLayoutPaddingBottom 13892c1ba9a961d4f96c26df260ee437655ad9e7c03eJeff Sharkey - ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY); 1390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Prepare the set of widgets to load previews for in the background 1392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int offset = (page - mNumAppsPages) * numItemsPerPage; 1393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = offset; i < Math.min(offset + numItemsPerPage, mWidgets.size()); ++i) { 1394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski items.add(mWidgets.get(i)); 1395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 139665665aac6387d644f0f40c6bdddf558f096b6e6eChristopher Tate 139765665aac6387d644f0f40c6bdddf558f096b6e6eChristopher Tate // Prepopulate the pages with the other widget info, and fill in the previews later 139865665aac6387d644f0f40c6bdddf558f096b6e6eChristopher Tate final PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page); 139965665aac6387d644f0f40c6bdddf558f096b6e6eChristopher Tate layout.setColumnCount(layout.getCellCountX()); 140065665aac6387d644f0f40c6bdddf558f096b6e6eChristopher Tate for (int i = 0; i < items.size(); ++i) { 140165665aac6387d644f0f40c6bdddf558f096b6e6eChristopher Tate Object rawInfo = items.get(i); 1402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PendingAddItemInfo createItemInfo = null; 1403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate( 1404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski R.layout.apps_customize_widget, layout, false); 1405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rawInfo instanceof AppWidgetProviderInfo) { 1406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the widget information 1407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo; 1408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createItemInfo = new PendingAddWidgetInfo(info, null, null); 1409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Determine the widget spans and min resize spans. 1411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] spanXY = Launcher.getSpanForWidget(mLauncher, info); 1412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createItemInfo.spanX = spanXY[0]; 1413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createItemInfo.spanY = spanXY[1]; 1414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, info); 1415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createItemInfo.minSpanX = minSpanXY[0]; 1416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createItemInfo.minSpanY = minSpanXY[1]; 1417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.applyFromAppWidgetProviderInfo(info, -1, spanXY); 1419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.setTag(createItemInfo); 14208732bd893ae507346dad068a33edcc4beb99faedKenny Root widget.setShortPressListener(this); 14218732bd893ae507346dad068a33edcc4beb99faedKenny Root } else if (rawInfo instanceof ResolveInfo) { 14228732bd893ae507346dad068a33edcc4beb99faedKenny Root // Fill in the shortcuts information 14238732bd893ae507346dad068a33edcc4beb99faedKenny Root ResolveInfo info = (ResolveInfo) rawInfo; 14248732bd893ae507346dad068a33edcc4beb99faedKenny Root createItemInfo = new PendingAddShortcutInfo(info.activityInfo); 14258732bd893ae507346dad068a33edcc4beb99faedKenny Root createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 1426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski createItemInfo.componentName = new ComponentName(info.activityInfo.packageName, 1427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski info.activityInfo.name); 1428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.applyFromResolveInfo(mPackageManager, info); 1429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.setTag(createItemInfo); 1430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.setOnClickListener(this); 1432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.setOnLongClickListener(this); 1433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.setOnTouchListener(this); 1434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.setOnKeyListener(this); 1435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Layout each widget 1437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int ix = i % mWidgetCountX; 1438dfeffd4c0ae165a3f225b818ef8d6f5d1cb89a2cDeepanshu Gupta int iy = i / mWidgetCountX; 1439dfeffd4c0ae165a3f225b818ef8d6f5d1cb89a2cDeepanshu Gupta GridLayout.LayoutParams lp = new GridLayout.LayoutParams( 1440dfeffd4c0ae165a3f225b818ef8d6f5d1cb89a2cDeepanshu Gupta GridLayout.spec(iy, GridLayout.LEFT), 1441dfeffd4c0ae165a3f225b818ef8d6f5d1cb89a2cDeepanshu Gupta GridLayout.spec(ix, GridLayout.TOP)); 1442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lp.width = cellWidth; 1443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lp.height = cellHeight; 1444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lp.setGravity(Gravity.TOP | Gravity.LEFT); 14458fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey if (ix > 0) lp.leftMargin = mWidgetWidthGap; 14468fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey if (iy > 0) lp.topMargin = mWidgetHeightGap; 14478fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey layout.addView(widget, lp); 14488fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey } 14498fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey 14508fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey // wait until a call on onLayout to start loading, because 14518fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey // PagedViewWidget.getPreviewSize() will return 0 if it hasn't been laid out 14528fc29cf1052fd951a3a0828b65506db30df89eceJeff Sharkey // TODO: can we do a measure/layout immediately? 14538a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey layout.setOnLayoutListener(new Runnable() { 145435871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey public void run() { 145535871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey // Load the widget previews 145635871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey int maxPreviewWidth = cellWidth; 145735871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey int maxPreviewHeight = cellHeight; 145835871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey if (layout.getChildCount() > 0) { 145935871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey PagedViewWidget w = (PagedViewWidget) layout.getChildAt(0); 146035871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey int[] maxSize = w.getPreviewSize(); 146135871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey maxPreviewWidth = maxSize[0]; 146235871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey maxPreviewHeight = maxSize[1]; 146335871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey } 146435871f2c2bb114806b4e3f109960b7f863d7885cJeff Sharkey if (immediate) { 1465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskPageData data = new AsyncTaskPageData(page, items, 1466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxPreviewWidth, maxPreviewHeight, null, null); 1467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski loadWidgetPreviewsInBackground(null, data); 1468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onSyncWidgetPageItems(data); 1469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mInTransition) { 1471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDeferredPrepareLoadWidgetPreviewsTasks.add(this); 1472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski prepareLoadWidgetPreviewsTask(page, items, 1474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski maxPreviewWidth, maxPreviewHeight, mWidgetCountX); 1475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski }); 1479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void loadWidgetPreviewsInBackground(AppsCustomizeAsyncTask task, 1481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AsyncTaskPageData data) { 1482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // loadWidgetPreviewsInBackground can be called without a task to load a set of widget 1483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // previews synchronously 1484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (task != null) { 1485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Ensure that this task starts running at the correct priority 1486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski task.syncThreadPriority(); 1487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Load each of the widget/shortcut previews 1490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<Object> items = data.items; 1491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<Bitmap> images = data.generatedImages; 1492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = items.size(); 1493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < count; ++i) { 1494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (task != null) { 1495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Ensure we haven't been cancelled yet 1496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (task.isCancelled()) break; 1497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Before work on each item, ensure that this task is running at the correct 1498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // priority 1499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski task.syncThreadPriority(); 1500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Object rawInfo = items.get(i); 1503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (rawInfo instanceof AppWidgetProviderInfo) { 1504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo; 1505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int[] cellSpans = Launcher.getSpanForWidget(mLauncher, info); 1506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxWidth = Math.min(data.maxImageWidth, 1508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetSpacingLayout.estimateCellWidth(cellSpans[0])); 1509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int maxHeight = Math.min(data.maxImageHeight, 1510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mWidgetSpacingLayout.estimateCellHeight(cellSpans[1])); 1511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap b = getWidgetPreview(info.provider, info.previewImage, info.icon, 1512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cellSpans[0], cellSpans[1], maxWidth, maxHeight); 1513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski images.add(b); 1514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (rawInfo instanceof ResolveInfo) { 1515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Fill in the shortcuts information 1516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResolveInfo info = (ResolveInfo) rawInfo; 1517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski images.add(getShortcutPreview(info, data.maxImageWidth, data.maxImageHeight)); 1518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void onSyncWidgetPageItems(AsyncTaskPageData data) { 1523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mInTransition) { 1524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDeferredSyncWidgetPageItems.add(data); 1525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return; 1526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 1528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int page = data.page; 1529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page); 1530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<Object> items = data.items; 1532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = items.size(); 1533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < count; ++i) { 1534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski PagedViewWidget widget = (PagedViewWidget) layout.getChildAt(i); 1535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (widget != null) { 1536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bitmap preview = data.generatedImages.get(i); 1537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski widget.applyPreview(new FastBitmapDrawable(preview), i); 1538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski layout.createHardwareLayer(); 1542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski invalidate(); 1543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Update all thread priorities 1545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator(); 1546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (iter.hasNext()) { 1547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next(); 1548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pageIndex = task.page; 1549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski task.setThreadPriority(getThreadPriorityForPage(pageIndex)); 1550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } finally { 1552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski data.cleanup(false); 1553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void syncPages() { 1558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski removeAllViews(); 1559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cancelAllTasks(); 1560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Context context = getContext(); 1562d4fd8c766da8a70e3359bbc7efbbc79496efe71aFyodor Kupolov for (int j = 0; j < mNumWidgetPages; ++j) { 1563d4fd8c766da8a70e3359bbc7efbbc79496efe71aFyodor Kupolov PagedViewGridLayout layout = new PagedViewGridLayout(context, mWidgetCountX, 1564d4fd8c766da8a70e3359bbc7efbbc79496efe71aFyodor Kupolov mWidgetCountY); 1565d4fd8c766da8a70e3359bbc7efbbc79496efe71aFyodor Kupolov setupPage(layout); 1566d4fd8c766da8a70e3359bbc7efbbc79496efe71aFyodor Kupolov addView(layout, new PagedView.LayoutParams(LayoutParams.MATCH_PARENT, 1567d4fd8c766da8a70e3359bbc7efbbc79496efe71aFyodor Kupolov LayoutParams.MATCH_PARENT)); 1568a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn } 1569a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn 1570a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn for (int i = 0; i < mNumAppsPages; ++i) { 1571a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn PagedViewCellLayout layout = new PagedViewCellLayout(context); 1572a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn setupPage(layout); 1573a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn addView(layout); 1574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void syncPageItems(int page, boolean immediate) { 1579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (page < mNumAppsPages) { 1580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syncAppsPageItems(page, immediate); 1581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski syncWidgetPageItems(page, immediate); 1583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We want our pages to be z-ordered such that the further a page is to the left, the higher 1587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // it is in the z-order. This is important to insure touch events are handled correctly. 1588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski View getPageAt(int index) { 1589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getChildAt(indexToPage(index)); 1590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1593a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn protected int indexToPage(int index) { 1594a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn return getChildCount() - index - 1; 1595a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn } 1596a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn 1597a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn // In apps customize, we have a scrolling effect which emulates pulling cards off of a stack. 1598a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn @Override 1599a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn protected void screenScrolled(int screenCenter) { 1600a750a63d639f6936af456df904fa6b9ba941885eDianne Hackborn super.screenScrolled(screenCenter); 1601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < getChildCount(); i++) { 1603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski View v = getPageAt(i); 1604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v != null) { 1605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float scrollProgress = getScrollProgress(screenCenter, v, i); 1606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float interpolatedProgress = 1608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mZInterpolator.getInterpolation(Math.abs(Math.min(scrollProgress, 0))); 1609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float scale = (1 - interpolatedProgress) + 1610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interpolatedProgress * TRANSITION_SCALE_FACTOR; 1611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float translationX = Math.min(0, scrollProgress) * v.getMeasuredWidth(); 1612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float alpha; 1614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (scrollProgress < 0) { 1616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski alpha = scrollProgress < 0 ? mAlphaInterpolator.getInterpolation( 1617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1 - Math.abs(scrollProgress)) : 1.0f; 16186762301a10ba1176dc97083bef6785ec169378ffSvet Ganov } else { 1619e8b6debd9b1035a8b8da102cfe476b71986b341cSvet Ganov // On large screens we need to fade the page as it nears its leftmost position 16206762301a10ba1176dc97083bef6785ec169378ffSvet Ganov alpha = mLeftScreenAlphaInterpolator.getInterpolation(1 - scrollProgress); 16216762301a10ba1176dc97083bef6785ec169378ffSvet Ganov } 16226762301a10ba1176dc97083bef6785ec169378ffSvet Ganov 1623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setCameraDistance(mDensity * CAMERA_DISTANCE); 1624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pageWidth = v.getMeasuredWidth(); 1625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pageHeight = v.getMeasuredHeight(); 1626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (PERFORM_OVERSCROLL_ROTATION) { 1628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i == 0 && scrollProgress < 0) { 1629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Overscroll to the left 1630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setPivotX(TRANSITION_PIVOT * pageWidth); 16313cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); 16323cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani scale = 1.0f; 16333cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani alpha = 1.0f; 1634fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn // On the first page, we don't want the page to have any lateral motion 1635fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn translationX = 0; 1636fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn } else if (i == getChildCount() - 1 && scrollProgress > 0) { 1637fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn // Overscroll to the right 1638fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn v.setPivotX((1 - TRANSITION_PIVOT) * pageWidth); 1639fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn v.setRotationY(-TRANSITION_MAX_ROTATION * scrollProgress); 1640fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn scale = 1.0f; 1641fd854ee58c5d56f84047007ead9f88a767ae956fDianne Hackborn alpha = 1.0f; 16423cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani // On the last page, we don't want the page to have any lateral motion. 16433cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani translationX = 0; 16443cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani } else { 16453cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani v.setPivotY(pageHeight / 2.0f); 16463cf75729d5a27b8ddd1ea174626dbcf0349a1d07Amith Yamasani v.setPivotX(pageWidth / 2.0f); 1647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setRotationY(0f); 1648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setTranslationX(translationX); 1652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setScaleX(scale); 1653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setScaleY(scale); 1654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setAlpha(alpha); 1655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If the view has 0 alpha, we set it to be invisible so as to prevent 1657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // it from accepting touches 1658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (alpha == 0) { 1659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setVisibility(INVISIBLE); 1660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (v.getVisibility() != VISIBLE) { 1661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v.setVisibility(VISIBLE); 1662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1665e0e413e2b17a0164e15c77f4ab51b3166f9111d2Dianne Hackborn } 1666e0e413e2b17a0164e15c77f4ab51b3166f9111d2Dianne Hackborn 1667e0e413e2b17a0164e15c77f4ab51b3166f9111d2Dianne Hackborn protected void overScroll(float amount) { 1668e0e413e2b17a0164e15c77f4ab51b3166f9111d2Dianne Hackborn acceleratedOverScroll(amount); 1669e0e413e2b17a0164e15c77f4ab51b3166f9111d2Dianne Hackborn } 1670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 1672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Used by the parent to get the content width to set the tab bar to 1673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return 1674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getPageContentWidth() { 1676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mContentWidth; 1677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski protected void onPageEndMoving() { 1681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super.onPageEndMoving(); 1682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mForceDrawAllChildrenNextFrame = true; 1683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We reset the save index when we change pages so that it will be recalculated on next 1684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // rotation 1685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSaveInstanceStateItemIndex = -1; 1686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 1689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * AllAppsView implementation 1690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void setup(Launcher launcher, DragController dragController) { 1693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLauncher = launcher; 1694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDragController = dragController; 1695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void zoom(float zoom, boolean animate) { 1698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO-APPS_CUSTOMIZE: Call back to mLauncher.zoomed() 1699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean isVisible() { 1702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (getVisibility() == VISIBLE); 1703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean isAnimating() { 1706282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 1707282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1708282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 1710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * We should call thise method whenever the core data changes (mApps, mWidgets) so that we can 1711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * appropriately determine when to invalidate the PagedView page data. In cases where the data 1712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * has yet to be set, we can requestLayout() and wait for onDataReady() to be called in the 1713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * next onMeasure() pass, which will trigger an invalidatePageData() itself. 1714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 1715282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void invalidateOnDataChange() { 1716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!isDataReady()) { 1717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The next layout pass will trigger data-ready if both widgets and apps are set, so 1718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // request a layout to trigger the page data when ready. 1719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski requestLayout(); 1720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 1721282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski cancelAllTasks(); 1722282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski invalidatePageData(); 1723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1724282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1727282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void setApps(ArrayList<ApplicationInfo> list) { 1728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mApps = list; 1729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR); 1730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePageCounts(); 1731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski invalidateOnDataChange(); 1732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) { 1734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We add it in place, in alphabetical order 1735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = list.size(); 1736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < count; ++i) { 1737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ApplicationInfo info = list.get(i); 1738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int index = Collections.binarySearch(mApps, info, LauncherModel.APP_NAME_COMPARATOR); 1739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0) { 1740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mApps.add(-(index + 1), info); 1741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void addApps(ArrayList<ApplicationInfo> list) { 1746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addAppsWithoutInvalidate(list); 1747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePageCounts(); 1748282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski invalidateOnDataChange(); 1749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) { 1751282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ComponentName removeComponent = item.intent.getComponent(); 1752282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int length = list.size(); 1753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < length; ++i) { 1754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ApplicationInfo info = list.get(i); 1755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (info.intent.getComponent().equals(removeComponent)) { 1756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i; 1757282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1758282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1759282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return -1; 1760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void removeAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) { 1762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // loop through all the apps and remove apps that have the same component 1763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int length = list.size(); 1764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0; i < length; ++i) { 1765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ApplicationInfo info = list.get(i); 1766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int removeIndex = findAppByComponent(mApps, info); 1767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (removeIndex > -1) { 1768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mApps.remove(removeIndex); 1769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1771282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1772282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void removeApps(ArrayList<ApplicationInfo> list) { 1774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski removeAppsWithoutInvalidate(list); 1775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePageCounts(); 1776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski invalidateOnDataChange(); 1777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void updateApps(ArrayList<ApplicationInfo> list) { 1780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We remove and re-add the updated applications list because it's properties may have 1781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // changed (ie. the title), and this will ensure that the items will be in their proper 1782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // place in the list. 1783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski removeAppsWithoutInvalidate(list); 1784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addAppsWithoutInvalidate(list); 1785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski updatePageCounts(); 1786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski invalidateOnDataChange(); 1787282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void reset() { 1791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // If we have reset, then we should not continue to restore the previous state 1792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mSaveInstanceStateItemIndex = -1; 1793282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1794282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppsCustomizeTabHost tabHost = getTabHost(); 1795282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String tag = tabHost.getCurrentTabTag(); 1796282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (tag != null) { 1797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!tag.equals(tabHost.getTabTagForContentType(ContentType.Applications))) { 1798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tabHost.setCurrentTabFromContent(ContentType.Applications); 1799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 18020f5caab5762d9ace8e7d87e29296bcb8fdfe9b4bAdam Lesinski if (mCurrentPage != 0) { 18030f5caab5762d9ace8e7d87e29296bcb8fdfe9b4bAdam Lesinski invalidatePageData(0); 18040f5caab5762d9ace8e7d87e29296bcb8fdfe9b4bAdam Lesinski } 18050f5caab5762d9ace8e7d87e29296bcb8fdfe9b4bAdam Lesinski } 18060f5caab5762d9ace8e7d87e29296bcb8fdfe9b4bAdam Lesinski 18070f5caab5762d9ace8e7d87e29296bcb8fdfe9b4bAdam Lesinski private AppsCustomizeTabHost getTabHost() { 1808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (AppsCustomizeTabHost) mLauncher.findViewById(R.id.apps_customize_pane); 1809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1811282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 1812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void dumpState() { 1813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: Dump information related to current list of Applications, Widgets, etc. 1814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ApplicationInfo.dumpApplicationInfoList(TAG, "mApps", mApps); 1815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski dumpAppWidgetProviderInfoList(TAG, "mWidgets", mWidgets); 1816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 1817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void dumpAppWidgetProviderInfoList(String tag, String label, 1819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ArrayList<Object> list) { 1820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Log.d(tag, label + " size=" + list.size()); 1821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (Object i: list) { 1822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (i instanceof AppWidgetProviderInfo) { 1823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski AppWidgetProviderInfo info = (AppWidgetProviderInfo) i; 1824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Log.d(tag, " label=\"" + info.label + "\" previewImage=" + info.previewImage 1825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + " resizeMode=" + info.resizeMode + " configure=" + info.configure 1826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + " initialLayout=" + info.initialLayout 1827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight); 1828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else if (i instanceof ResolveInfo) { 18292ee3c1e189819cc6efb4d7de24f1438bdb824087Jeff Sharkey ResolveInfo info = (ResolveInfo) i; 18302ee3c1e189819cc6efb4d7de24f1438bdb824087Jeff Sharkey Log.d(tag, " label=\"" + info.loadLabel(mPackageManager) + "\" icon=" 18312ee3c1e189819cc6efb4d7de24f1438bdb824087Jeff Sharkey + info.icon); 18322ee3c1e189819cc6efb4d7de24f1438bdb824087Jeff Sharkey } 18332ee3c1e189819cc6efb4d7de24f1438bdb824087Jeff Sharkey } 18342ee3c1e189819cc6efb4d7de24f1438bdb824087Jeff Sharkey } 18354dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen 18364dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen @Override 18374dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen public void surrender() { 18384dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we 18394dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen // should stop this now. 18404dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen 18414dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen // Stop all background tasks 18424dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen cancelAllTasks(); 18434dfe4d43ce5634f059a3ba669e3cac4551c3a3eeJens Ole Lauridsen } 18447a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey 1845d15459197f71f8cc940e2b057b399117df282f2cDiego Perez @Override 1846d15459197f71f8cc940e2b057b399117df282f2cDiego Perez public void iconPressed(PagedViewIcon icon) { 1847d15459197f71f8cc940e2b057b399117df282f2cDiego Perez // Reset the previously pressed icon and store a reference to the pressed icon so that 1848d15459197f71f8cc940e2b057b399117df282f2cDiego Perez // we can reset it on return to Launcher (in Launcher.onResume()) 1849d15459197f71f8cc940e2b057b399117df282f2cDiego Perez if (mPressedIcon != null) { 1850d15459197f71f8cc940e2b057b399117df282f2cDiego Perez mPressedIcon.resetDrawableState(); 1851d15459197f71f8cc940e2b057b399117df282f2cDiego Perez } 1852d15459197f71f8cc940e2b057b399117df282f2cDiego Perez mPressedIcon = icon; 1853d15459197f71f8cc940e2b057b399117df282f2cDiego Perez } 18547a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey 18558a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey public void resetDrawableState() { 18567a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey if (mPressedIcon != null) { 18577a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey mPressedIcon.resetDrawableState(); 18587a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey mPressedIcon = null; 18597a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey } 18607a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey } 18618a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey 18627a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey /* 18637a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey * We load an extra page on each side to prevent flashes from scrolling and loading of the 18647a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey * widget previews in the background with the AsyncTasks. 18657a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey */ 18667a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey final static int sLookBehindPageCount = 2; 18678a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey final static int sLookAheadPageCount = 2; 18687a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey protected int getAssociatedLowerPageBound(int page) { 18697a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey final int count = getChildCount(); 18707a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1); 18717a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey int windowMinIndex = Math.max(Math.min(page - sLookBehindPageCount, count - windowSize), 0); 18728a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey return windowMinIndex; 18737a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey } 18747a30a30ebece75f4a73fa604d4c7721d28eecc16Jeff Sharkey protected int getAssociatedUpperPageBound(int page) { 187591253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta final int count = getChildCount(); 187691253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1); 187791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta int windowMaxIndex = Math.min(Math.max(page + sLookAheadPageCount, windowSize - 1), 187891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta count - 1); 187991253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta return windowMaxIndex; 188091253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 188191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 188291253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta @Override 188391253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta protected String getCurrentPageDescription() { 188491253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage; 188591253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta int stringId = R.string.default_scroll_format; 188691253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta int count = 0; 188791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 188891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta if (page < mNumAppsPages) { 188991253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta stringId = R.string.apps_customize_apps_scroll_format; 189091253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta count = mNumAppsPages; 189191253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } else { 189291253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta page -= mNumAppsPages; 189391253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta stringId = R.string.apps_customize_widgets_scroll_format; 189491253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta count = mNumWidgetPages; 189591253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 189691253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta 189791253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta return String.format(getContext().getString(stringId), page + 1, count); 189891253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta } 189991253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta} 190091253ed04696ecd57636472dd8ac74660f65c5c2Deepanshu Gupta