TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / android / appmgr / src / org / anbox / appmgr / AppsLoader.java
1 /*
2  * The MIT License (MIT)
3  *
4  * Copyright 2016 Arnab Chakraborty. http://arnab.ch
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy of this
7  * software and associated documentation files (the "Software"), to deal in the Software
8  * without restriction, including without limitation the rights to use, copy, modify,
9  * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to the following
11  * conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies
14  * or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
17  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 package org.anbox.appmgr;
25
26 import android.content.Context;
27 import android.content.pm.ApplicationInfo;
28 import android.content.pm.PackageManager;
29 import android.support.v4.content.AsyncTaskLoader;
30
31 import java.text.Collator;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.Comparator;
36
37 /**
38  * @credit http://developer.android.com/reference/android/content/AsyncTaskLoader.html
39  */
40 public class AppsLoader extends AsyncTaskLoader<ArrayList<AppModel>> {
41     ArrayList<AppModel> mInstalledApps;
42
43     final PackageManager mPm;
44     PackageIntentReceiver mPackageObserver;
45
46     public AppsLoader(Context context) {
47         super(context);
48
49         mPm = context.getPackageManager();
50     }
51
52     @Override
53     public ArrayList<AppModel> loadInBackground() {
54         // retrieve the list of installed applications
55         List<ApplicationInfo> apps = mPm.getInstalledApplications(0);
56
57         if (apps == null) {
58             apps = new ArrayList<ApplicationInfo>();
59         }
60
61         final Context context = getContext();
62
63         // create corresponding apps and load their labels
64         ArrayList<AppModel> items = new ArrayList<AppModel>(apps.size());
65         for (int i = 0; i < apps.size(); i++) {
66             String pkg = apps.get(i).packageName;
67
68             // only apps which are launchable
69             if (context.getPackageManager().getLaunchIntentForPackage(pkg) != null) {
70                 AppModel app = new AppModel(context, apps.get(i));
71                 app.loadLabel(context);
72                 items.add(app);
73             }
74         }
75
76         // sort the list
77         Collections.sort(items, ALPHA_COMPARATOR);
78
79         return items;
80     }
81
82     @Override
83     public void deliverResult(ArrayList<AppModel> apps) {
84         if (isReset()) {
85             // An async query came in while the loader is stopped.  We
86             // don't need the result.
87             if (apps != null) {
88                 onReleaseResources(apps);
89             }
90         }
91
92         ArrayList<AppModel> oldApps = apps;
93         mInstalledApps = apps;
94
95         if (isStarted()) {
96             // If the Loader is currently started, we can immediately
97             // deliver its results.
98             super.deliverResult(apps);
99         }
100
101         // At this point we can release the resources associated with
102         // 'oldApps' if needed; now that the new result is delivered we
103         // know that it is no longer in use.
104         if (oldApps != null) {
105             onReleaseResources(oldApps);
106         }
107     }
108
109     @Override
110     protected void onStartLoading() {
111         if (mInstalledApps != null) {
112             // If we currently have a result available, deliver it
113             // immediately.
114             deliverResult(mInstalledApps);
115         }
116
117         // watch for changes in app install and uninstall operation
118         if (mPackageObserver == null) {
119             mPackageObserver = new PackageIntentReceiver(this);
120         }
121
122         if (takeContentChanged() || mInstalledApps == null ) {
123             // If the data has changed since the last time it was loaded
124             // or is not currently available, start a load.
125             forceLoad();
126         }
127     }
128
129     @Override
130     protected void onStopLoading() {
131         // Attempt to cancel the current load task if possible.
132         cancelLoad();
133     }
134
135     @Override
136     public void onCanceled(ArrayList<AppModel> apps) {
137         super.onCanceled(apps);
138
139         // At this point we can release the resources associated with 'apps'
140         // if needed.
141         onReleaseResources(apps);
142     }
143
144     @Override
145     protected void onReset() {
146         // Ensure the loader is stopped
147         onStopLoading();
148
149         // At this point we can release the resources associated with 'apps'
150         // if needed.
151         if (mInstalledApps != null) {
152             onReleaseResources(mInstalledApps);
153             mInstalledApps = null;
154         }
155
156         // Stop monitoring for changes.
157         if (mPackageObserver != null) {
158             getContext().unregisterReceiver(mPackageObserver);
159             mPackageObserver = null;
160         }
161     }
162
163     /**
164      * Helper method to do the cleanup work if needed, for example if we're
165      * using Cursor, then we should be closing it here
166      *
167      * @param apps
168      */
169     protected void onReleaseResources(ArrayList<AppModel> apps) {
170         // do nothing
171     }
172
173
174     /**
175      * Perform alphabetical comparison of application entry objects.
176      */
177     public static final Comparator<AppModel> ALPHA_COMPARATOR = new Comparator<AppModel>() {
178         private final Collator sCollator = Collator.getInstance();
179         @Override
180         public int compare(AppModel object1, AppModel object2) {
181             return sCollator.compare(object1.getLabel(), object2.getLabel());
182         }
183     };
184 }