14eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey/* 24eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * Copyright (C) 2013 The Android Open Source Project 34eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * 44eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 54eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * you may not use this file except in compliance with the License. 64eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * You may obtain a copy of the License at 74eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * 84eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 94eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * 104eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * Unless required by applicable law or agreed to in writing, software 114eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 124eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * See the License for the specific language governing permissions and 144eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey * limitations under the License. 154eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey */ 164eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 174eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeypackage com.android.documentsui; 184eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 194eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.app.ActivityManager; 204eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.app.Application; 214eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.BroadcastReceiver; 227aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.content.ContentProviderClient; 237aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.content.ContentResolver; 244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.Context; 254eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.Intent; 264eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.IntentFilter; 274eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.graphics.Point; 28a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkeyimport android.net.Uri; 297aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.os.RemoteException; 307aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkeyimport android.text.format.DateUtils; 314eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 324eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeypublic class DocumentsApplication extends Application { 337aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS; 347aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private RootsCache mRoots; 364eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private Point mThumbnailsSize; 374eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private ThumbnailCache mThumbnails; 384eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 394eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public static RootsCache getRootsCache(Context context) { 404eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return ((DocumentsApplication) context.getApplicationContext()).mRoots; 414eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 424eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 434eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public static ThumbnailCache getThumbnailsCache(Context context, Point size) { 444eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final DocumentsApplication app = (DocumentsApplication) context.getApplicationContext(); 454eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbnails = app.mThumbnails; 464eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (!size.equals(app.mThumbnailsSize)) { 474eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey thumbnails.evictAll(); 484eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey app.mThumbnailsSize = size; 494eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 504eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return thumbnails; 514eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 524eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 537aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey public static ContentProviderClient acquireUnstableProviderOrThrow( 547aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey ContentResolver resolver, String authority) throws RemoteException { 557aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey final ContentProviderClient client = resolver.acquireUnstableContentProviderClient( 567aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey authority); 577aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey if (client == null) { 587aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey throw new RemoteException("Failed to acquire provider for " + authority); 597aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } 607aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey client.setDetectNotResponding(PROVIDER_ANR_TIMEOUT); 617aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey return client; 627aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey } 637aa7601c09ab5d87cc15a0ed9a8f511d494a4cbcJeff Sharkey 644eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey @Override 654eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public void onCreate() { 664eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 674eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int memoryClassBytes = am.getMemoryClass() * 1024 * 1024; 684eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 694eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mRoots = new RootsCache(this); 70a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mRoots.updateAsync(); 71a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey 724eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbnails = new ThumbnailCache(memoryClassBytes / 4); 734eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 744eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final IntentFilter packageFilter = new IntentFilter(); 754eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 764eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); 774eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 7846de7b50243d3896fe97d1ee7a00258085cea1caJeff Sharkey packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); 794eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey packageFilter.addDataScheme("package"); 804ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey registerReceiver(mCacheReceiver, packageFilter); 814ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 824ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final IntentFilter localeFilter = new IntentFilter(); 834ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED); 844ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey registerReceiver(mCacheReceiver, localeFilter); 854eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 864eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 874eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey @Override 884eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public void onTrimMemory(int level) { 894eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey super.onTrimMemory(level); 904eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 914eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (level >= TRIM_MEMORY_MODERATE) { 924eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbnails.evictAll(); 934eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (level >= TRIM_MEMORY_BACKGROUND) { 944eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbnails.trimToSize(mThumbnails.size() / 2); 954eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 964eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 974eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 984ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() { 994eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey @Override 1004eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public void onReceive(Context context, Intent intent) { 101a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final Uri data = intent.getData(); 102a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey if (data != null) { 103a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey final String packageName = data.getSchemeSpecificPart(); 104a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mRoots.updatePackageAsync(packageName); 105a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } else { 106a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey mRoots.updateAsync(); 107a9ce049db87259e302e2368d2a4a1c11a94fd831Jeff Sharkey } 1084eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 1094eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey }; 1104eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey} 111