1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.documentsui;
18 
19 import android.app.ActivityManager;
20 import android.app.Application;
21 import android.content.BroadcastReceiver;
22 import android.content.ContentProviderClient;
23 import android.content.ContentResolver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.graphics.Point;
28 import android.net.Uri;
29 import android.os.RemoteException;
30 import android.text.format.DateUtils;
31 
32 public class DocumentsApplication extends Application {
33     private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS;
34 
35     private RootsCache mRoots;
36     private Point mThumbnailsSize;
37     private ThumbnailCache mThumbnails;
38 
getRootsCache(Context context)39     public static RootsCache getRootsCache(Context context) {
40         return ((DocumentsApplication) context.getApplicationContext()).mRoots;
41     }
42 
getThumbnailsCache(Context context, Point size)43     public static ThumbnailCache getThumbnailsCache(Context context, Point size) {
44         final DocumentsApplication app = (DocumentsApplication) context.getApplicationContext();
45         final ThumbnailCache thumbnails = app.mThumbnails;
46         if (!size.equals(app.mThumbnailsSize)) {
47             thumbnails.evictAll();
48             app.mThumbnailsSize = size;
49         }
50         return thumbnails;
51     }
52 
acquireUnstableProviderOrThrow( ContentResolver resolver, String authority)53     public static ContentProviderClient acquireUnstableProviderOrThrow(
54             ContentResolver resolver, String authority) throws RemoteException {
55         final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
56                 authority);
57         if (client == null) {
58             throw new RemoteException("Failed to acquire provider for " + authority);
59         }
60         client.setDetectNotResponding(PROVIDER_ANR_TIMEOUT);
61         return client;
62     }
63 
64     @Override
onCreate()65     public void onCreate() {
66         super.onCreate();
67 
68         final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
69         final int memoryClassBytes = am.getMemoryClass() * 1024 * 1024;
70 
71         mRoots = new RootsCache(this);
72         mRoots.updateAsync(false);
73 
74         mThumbnails = new ThumbnailCache(memoryClassBytes / 4);
75 
76         final IntentFilter packageFilter = new IntentFilter();
77         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
78         packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
79         packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
80         packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
81         packageFilter.addDataScheme("package");
82         registerReceiver(mCacheReceiver, packageFilter);
83 
84         final IntentFilter localeFilter = new IntentFilter();
85         localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
86         registerReceiver(mCacheReceiver, localeFilter);
87     }
88 
89     @Override
onTrimMemory(int level)90     public void onTrimMemory(int level) {
91         super.onTrimMemory(level);
92 
93         if (level >= TRIM_MEMORY_MODERATE) {
94             mThumbnails.evictAll();
95         } else if (level >= TRIM_MEMORY_BACKGROUND) {
96             mThumbnails.trimToSize(mThumbnails.size() / 2);
97         }
98     }
99 
100     private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() {
101         @Override
102         public void onReceive(Context context, Intent intent) {
103             final Uri data = intent.getData();
104             if (data != null) {
105                 final String packageName = data.getSchemeSpecificPart();
106                 mRoots.updatePackageAsync(packageName);
107             } else {
108                 mRoots.updateAsync(true);
109             }
110         }
111     };
112 }
113