Rework manage applications to be page-able.
Turn everything around so that we can have multiple list views with their own adapters. Switch to using a ViewPager for managing the different lists. Smile! Change-Id: I9c102abb06cf67f313a8696507aa4597b38c7ab9
This commit is contained in:
@@ -2,7 +2,7 @@ LOCAL_PATH:= $(call my-dir)
|
|||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_JAVA_LIBRARIES := bouncycastle
|
LOCAL_JAVA_LIBRARIES := bouncycastle
|
||||||
LOCAL_STATIC_JAVA_LIBRARIES := guava
|
LOCAL_STATIC_JAVA_LIBRARIES := guava android-support-v4
|
||||||
|
|
||||||
LOCAL_MODULE_TAGS := optional
|
LOCAL_MODULE_TAGS := optional
|
||||||
|
|
||||||
|
10
res/layout/manage_applications.xml → res/layout/manage_applications_apps.xml
Executable file → Normal file
10
res/layout/manage_applications.xml → res/layout/manage_applications_apps.xml
Executable file → Normal file
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Copyright (C) 2008 The Android Open Source Project
|
<!-- Copyright (C) 2012 The Android Open Source Project
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -83,12 +83,6 @@
|
|||||||
</view>
|
</view>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<view class="com.android.settings.applications.RunningProcessesView"
|
|
||||||
android:id="@+id/running_processes"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/loading_container"
|
<LinearLayout android:id="@+id/loading_container"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -110,4 +104,4 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
41
res/layout/manage_applications_content.xml
Normal file
41
res/layout/manage_applications_content.xml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 2012, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.support.v4.view.ViewPager
|
||||||
|
android:id="@+id/pager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1">
|
||||||
|
<android.support.v4.view.PagerTabStrip
|
||||||
|
android:id="@+id/tabs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top">
|
||||||
|
</android.support.v4.view.PagerTabStrip>
|
||||||
|
</android.support.v4.view.ViewPager>
|
||||||
|
|
||||||
|
</LinearLayout>
|
47
res/layout/manage_applications_running.xml
Normal file
47
res/layout/manage_applications_running.xml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2012 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" >
|
||||||
|
<view class="com.android.settings.applications.RunningProcessesView"
|
||||||
|
android:id="@+id/running_processes"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout android:id="@+id/loading_container"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginLeft="@*android:dimen/preference_fragment_padding_side"
|
||||||
|
android:layout_marginRight="@*android:dimen/preference_fragment_padding_side"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ProgressBar style="?android:attr/progressBarStyleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<TextView android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:text="@string/settings_safetylegal_activity_loading"
|
||||||
|
android:paddingTop="4dip"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
@@ -1,51 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
/*
|
|
||||||
**
|
|
||||||
** Copyright 2012, The Android Open Source Project
|
|
||||||
**
|
|
||||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
** you may not use this file except in compliance with the License.
|
|
||||||
** You may obtain a copy of the License at
|
|
||||||
**
|
|
||||||
** http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
**
|
|
||||||
** Unless required by applicable law or agreed to in writing, software
|
|
||||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
** See the License for the specific language governing permissions and
|
|
||||||
** limitations under the License.
|
|
||||||
*/
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/spinner"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="48sp"
|
|
||||||
android:minWidth="180dp"
|
|
||||||
android:layout_marginLeft="@*android:dimen/preference_fragment_padding_side"
|
|
||||||
android:layout_marginRight="@*android:dimen/preference_fragment_padding_side"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginLeft="@*android:dimen/preference_fragment_padding_side"
|
|
||||||
android:layout_marginRight="@*android:dimen/preference_fragment_padding_side"
|
|
||||||
android:scaleType="fitXY"
|
|
||||||
android:src="?android:attr/listDivider" />
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/spinner_content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dip"
|
|
||||||
android:layout_weight="1" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@@ -42,7 +42,7 @@ public class AppViewHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSizeText(ManageApplications ma, int whichSize) {
|
void updateSizeText(CharSequence invalidSizeStr, int whichSize) {
|
||||||
if (ManageApplications.DEBUG) Log.i(ManageApplications.TAG, "updateSizeText of " + entry.label + " " + entry
|
if (ManageApplications.DEBUG) Log.i(ManageApplications.TAG, "updateSizeText of " + entry.label + " " + entry
|
||||||
+ ": " + entry.sizeStr);
|
+ ": " + entry.sizeStr);
|
||||||
if (entry.sizeStr != null) {
|
if (entry.sizeStr != null) {
|
||||||
@@ -58,7 +58,7 @@ public class AppViewHolder {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (entry.size == ApplicationsState.SIZE_INVALID) {
|
} else if (entry.size == ApplicationsState.SIZE_INVALID) {
|
||||||
appSize.setText(ma.mInvalidSizeStr);
|
appSize.setText(invalidSizeStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -227,24 +227,21 @@ public class ApplicationsState {
|
|||||||
PackageIntentReceiver mPackageIntentReceiver;
|
PackageIntentReceiver mPackageIntentReceiver;
|
||||||
|
|
||||||
boolean mResumed;
|
boolean mResumed;
|
||||||
Callbacks mCurCallbacks;
|
|
||||||
|
|
||||||
// Information about all applications. Synchronize on mAppEntries
|
// Information about all applications. Synchronize on mEntriesMap
|
||||||
// to protect access to these.
|
// to protect access to these.
|
||||||
|
final ArrayList<Session> mSessions = new ArrayList<Session>();
|
||||||
|
final ArrayList<Session> mRebuildingSessions = new ArrayList<Session>();
|
||||||
final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges();
|
final InterestingConfigChanges mInterestingConfigChanges = new InterestingConfigChanges();
|
||||||
final HashMap<String, AppEntry> mEntriesMap = new HashMap<String, AppEntry>();
|
final HashMap<String, AppEntry> mEntriesMap = new HashMap<String, AppEntry>();
|
||||||
final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>();
|
final ArrayList<AppEntry> mAppEntries = new ArrayList<AppEntry>();
|
||||||
List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();
|
List<ApplicationInfo> mApplications = new ArrayList<ApplicationInfo>();
|
||||||
long mCurId = 1;
|
long mCurId = 1;
|
||||||
String mCurComputingSizePkg;
|
String mCurComputingSizePkg;
|
||||||
|
boolean mSessionsChanged;
|
||||||
|
|
||||||
// Rebuilding of app list. Synchronized on mRebuildSync.
|
// Temporary for dispatching session callbacks. Only touched by main thread.
|
||||||
final Object mRebuildSync = new Object();
|
final ArrayList<Session> mActiveSessions = new ArrayList<Session>();
|
||||||
boolean mRebuildRequested;
|
|
||||||
boolean mRebuildAsync;
|
|
||||||
AppFilter mRebuildFilter;
|
|
||||||
Comparator<AppEntry> mRebuildComparator;
|
|
||||||
ArrayList<AppEntry> mRebuildResult;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives notifications when applications are added/removed.
|
* Receives notifications when applications are added/removed.
|
||||||
@@ -262,6 +259,9 @@ public class ApplicationsState {
|
|||||||
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
|
sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
|
||||||
mContext.registerReceiver(this, sdFilter);
|
mContext.registerReceiver(this, sdFilter);
|
||||||
}
|
}
|
||||||
|
void unregisterReceiver() {
|
||||||
|
mContext.unregisterReceiver(this);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
String actionStr = intent.getAction();
|
String actionStr = intent.getAction();
|
||||||
@@ -300,6 +300,21 @@ public class ApplicationsState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rebuildActiveSessions() {
|
||||||
|
synchronized (mEntriesMap) {
|
||||||
|
if (!mSessionsChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mActiveSessions.clear();
|
||||||
|
for (int i=0; i<mSessions.size(); i++) {
|
||||||
|
Session s = mSessions.get(i);
|
||||||
|
if (s.mResumed) {
|
||||||
|
mActiveSessions.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MainHandler extends Handler {
|
class MainHandler extends Handler {
|
||||||
static final int MSG_REBUILD_COMPLETE = 1;
|
static final int MSG_REBUILD_COMPLETE = 1;
|
||||||
static final int MSG_PACKAGE_LIST_CHANGED = 2;
|
static final int MSG_PACKAGE_LIST_CHANGED = 2;
|
||||||
@@ -310,35 +325,39 @@ public class ApplicationsState {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
|
rebuildActiveSessions();
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_REBUILD_COMPLETE: {
|
case MSG_REBUILD_COMPLETE: {
|
||||||
if (mCurCallbacks != null) {
|
Session s = (Session)msg.obj;
|
||||||
mCurCallbacks.onRebuildComplete((ArrayList<AppEntry>)msg.obj);
|
if (mActiveSessions.contains(s)) {
|
||||||
|
s.mCallbacks.onRebuildComplete(s.mLastAppList);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case MSG_PACKAGE_LIST_CHANGED: {
|
case MSG_PACKAGE_LIST_CHANGED: {
|
||||||
if (mCurCallbacks != null) {
|
for (int i=0; i<mActiveSessions.size(); i++) {
|
||||||
mCurCallbacks.onPackageListChanged();
|
mActiveSessions.get(i).mCallbacks.onPackageListChanged();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case MSG_PACKAGE_ICON_CHANGED: {
|
case MSG_PACKAGE_ICON_CHANGED: {
|
||||||
if (mCurCallbacks != null) {
|
for (int i=0; i<mActiveSessions.size(); i++) {
|
||||||
mCurCallbacks.onPackageIconChanged();
|
mActiveSessions.get(i).mCallbacks.onPackageIconChanged();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case MSG_PACKAGE_SIZE_CHANGED: {
|
case MSG_PACKAGE_SIZE_CHANGED: {
|
||||||
if (mCurCallbacks != null) {
|
for (int i=0; i<mActiveSessions.size(); i++) {
|
||||||
mCurCallbacks.onPackageSizeChanged((String)msg.obj);
|
mActiveSessions.get(i).mCallbacks.onPackageSizeChanged(
|
||||||
|
(String)msg.obj);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case MSG_ALL_SIZES_COMPUTED: {
|
case MSG_ALL_SIZES_COMPUTED: {
|
||||||
if (mCurCallbacks != null) {
|
for (int i=0; i<mActiveSessions.size(); i++) {
|
||||||
mCurCallbacks.onAllSizesComputed();
|
mActiveSessions.get(i).mCallbacks.onAllSizesComputed();
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case MSG_RUNNING_STATE_CHANGED: {
|
case MSG_RUNNING_STATE_CHANGED: {
|
||||||
if (mCurCallbacks != null) {
|
for (int i=0; i<mActiveSessions.size(); i++) {
|
||||||
mCurCallbacks.onRunningStateChanged(msg.arg1 != 0);
|
mActiveSessions.get(i).mCallbacks.onRunningStateChanged(
|
||||||
|
msg.arg1 != 0);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@@ -391,157 +410,226 @@ public class ApplicationsState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resume(Callbacks callbacks) {
|
public class Session {
|
||||||
if (DEBUG_LOCKING) Log.v(TAG, "resume about to acquire lock...");
|
final Callbacks mCallbacks;
|
||||||
synchronized (mEntriesMap) {
|
boolean mResumed;
|
||||||
mCurCallbacks = callbacks;
|
|
||||||
mResumed = true;
|
|
||||||
if (mPackageIntentReceiver == null) {
|
|
||||||
mPackageIntentReceiver = new PackageIntentReceiver();
|
|
||||||
mPackageIntentReceiver.registerReceiver();
|
|
||||||
}
|
|
||||||
mApplications = mPm.getInstalledApplications(
|
|
||||||
PackageManager.GET_UNINSTALLED_PACKAGES |
|
|
||||||
PackageManager.GET_DISABLED_COMPONENTS);
|
|
||||||
if (mApplications == null) {
|
|
||||||
mApplications = new ArrayList<ApplicationInfo>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
|
// Rebuilding of app list. Synchronized on mRebuildSync.
|
||||||
// If an interesting part of the configuration has changed, we
|
final Object mRebuildSync = new Object();
|
||||||
// should completely reload the app entries.
|
boolean mRebuildRequested;
|
||||||
mEntriesMap.clear();
|
boolean mRebuildAsync;
|
||||||
mAppEntries.clear();
|
AppFilter mRebuildFilter;
|
||||||
} else {
|
Comparator<AppEntry> mRebuildComparator;
|
||||||
for (int i=0; i<mAppEntries.size(); i++) {
|
ArrayList<AppEntry> mRebuildResult;
|
||||||
mAppEntries.get(i).sizeStale = true;
|
ArrayList<AppEntry> mLastAppList;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<mApplications.size(); i++) {
|
Session(Callbacks callbacks) {
|
||||||
final ApplicationInfo info = mApplications.get(i);
|
mCallbacks = callbacks;
|
||||||
// Need to trim out any applications that are disabled by
|
}
|
||||||
// something different than the user.
|
|
||||||
if (!info.enabled && info.enabledSetting
|
public void resume() {
|
||||||
!= PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
|
if (DEBUG_LOCKING) Log.v(TAG, "resume about to acquire lock...");
|
||||||
mApplications.remove(i);
|
synchronized (mEntriesMap) {
|
||||||
i--;
|
if (!mResumed) {
|
||||||
continue;
|
mResumed = true;
|
||||||
|
mSessionsChanged = true;
|
||||||
|
doResumeIfNeededLocked();
|
||||||
}
|
}
|
||||||
final AppEntry entry = mEntriesMap.get(info.packageName);
|
|
||||||
if (entry != null) {
|
|
||||||
entry.info = info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mCurComputingSizePkg = null;
|
|
||||||
if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
|
|
||||||
mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
|
|
||||||
}
|
}
|
||||||
if (DEBUG_LOCKING) Log.v(TAG, "...resume releasing lock");
|
if (DEBUG_LOCKING) Log.v(TAG, "...resume releasing lock");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void pause() {
|
public void pause() {
|
||||||
if (DEBUG_LOCKING) Log.v(TAG, "pause about to acquire lock...");
|
if (DEBUG_LOCKING) Log.v(TAG, "pause about to acquire lock...");
|
||||||
synchronized (mEntriesMap) {
|
synchronized (mEntriesMap) {
|
||||||
mCurCallbacks = null;
|
if (mResumed) {
|
||||||
mResumed = false;
|
mResumed = false;
|
||||||
if (DEBUG_LOCKING) Log.v(TAG, "...pause releasing lock");
|
mSessionsChanged = true;
|
||||||
}
|
mBackgroundHandler.removeMessages(BackgroundHandler.MSG_REBUILD_LIST, this);
|
||||||
}
|
doPauseIfNeededLocked();
|
||||||
|
|
||||||
// Creates a new list of app entries with the given filter and comparator.
|
|
||||||
ArrayList<AppEntry> rebuild(AppFilter filter, Comparator<AppEntry> comparator) {
|
|
||||||
synchronized (mRebuildSync) {
|
|
||||||
mRebuildRequested = true;
|
|
||||||
mRebuildAsync = false;
|
|
||||||
mRebuildFilter = filter;
|
|
||||||
mRebuildComparator = comparator;
|
|
||||||
mRebuildResult = null;
|
|
||||||
if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_REBUILD_LIST)) {
|
|
||||||
mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_REBUILD_LIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will wait for .25s for the list to be built.
|
|
||||||
long waitend = SystemClock.uptimeMillis()+250;
|
|
||||||
|
|
||||||
while (mRebuildResult == null) {
|
|
||||||
long now = SystemClock.uptimeMillis();
|
|
||||||
if (now >= waitend) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
mRebuildSync.wait(waitend - now);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
}
|
}
|
||||||
|
if (DEBUG_LOCKING) Log.v(TAG, "...pause releasing lock");
|
||||||
}
|
}
|
||||||
|
|
||||||
mRebuildAsync = true;
|
|
||||||
|
|
||||||
return mRebuildResult;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleRebuildList() {
|
|
||||||
AppFilter filter;
|
|
||||||
Comparator<AppEntry> comparator;
|
|
||||||
synchronized (mRebuildSync) {
|
|
||||||
if (!mRebuildRequested) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
filter = mRebuildFilter;
|
|
||||||
comparator = mRebuildComparator;
|
|
||||||
mRebuildRequested = false;
|
|
||||||
mRebuildFilter = null;
|
|
||||||
mRebuildComparator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
|
// Creates a new list of app entries with the given filter and comparator.
|
||||||
|
ArrayList<AppEntry> rebuild(AppFilter filter, Comparator<AppEntry> comparator) {
|
||||||
if (filter != null) {
|
synchronized (mRebuildSync) {
|
||||||
filter.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ApplicationInfo> apps;
|
|
||||||
synchronized (mEntriesMap) {
|
|
||||||
apps = new ArrayList<ApplicationInfo>(mApplications);
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<AppEntry> filteredApps = new ArrayList<AppEntry>();
|
|
||||||
if (DEBUG) Log.i(TAG, "Rebuilding...");
|
|
||||||
for (int i=0; i<apps.size(); i++) {
|
|
||||||
ApplicationInfo info = apps.get(i);
|
|
||||||
if (filter == null || filter.filterApp(info)) {
|
|
||||||
synchronized (mEntriesMap) {
|
synchronized (mEntriesMap) {
|
||||||
if (DEBUG_LOCKING) Log.v(TAG, "rebuild acquired lock");
|
mRebuildingSessions.add(this);
|
||||||
AppEntry entry = getEntryLocked(info);
|
mRebuildRequested = true;
|
||||||
entry.ensureLabel(mContext);
|
mRebuildAsync = false;
|
||||||
if (DEBUG) Log.i(TAG, "Using " + info.packageName + ": " + entry);
|
mRebuildFilter = filter;
|
||||||
filteredApps.add(entry);
|
mRebuildComparator = comparator;
|
||||||
if (DEBUG_LOCKING) Log.v(TAG, "rebuild releasing lock");
|
mRebuildResult = null;
|
||||||
|
if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_REBUILD_LIST)) {
|
||||||
|
Message msg = mBackgroundHandler.obtainMessage(
|
||||||
|
BackgroundHandler.MSG_REBUILD_LIST);
|
||||||
|
mBackgroundHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We will wait for .25s for the list to be built.
|
||||||
|
long waitend = SystemClock.uptimeMillis()+250;
|
||||||
|
|
||||||
|
while (mRebuildResult == null) {
|
||||||
|
long now = SystemClock.uptimeMillis();
|
||||||
|
if (now >= waitend) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mRebuildSync.wait(waitend - now);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mRebuildAsync = true;
|
||||||
|
|
||||||
|
return mRebuildResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(filteredApps, comparator);
|
void handleRebuildList() {
|
||||||
|
AppFilter filter;
|
||||||
|
Comparator<AppEntry> comparator;
|
||||||
|
synchronized (mRebuildSync) {
|
||||||
|
if (!mRebuildRequested) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (mRebuildSync) {
|
filter = mRebuildFilter;
|
||||||
if (!mRebuildRequested) {
|
comparator = mRebuildComparator;
|
||||||
if (!mRebuildAsync) {
|
mRebuildRequested = false;
|
||||||
mRebuildResult = filteredApps;
|
mRebuildFilter = null;
|
||||||
mRebuildSync.notifyAll();
|
mRebuildComparator = null;
|
||||||
} else {
|
}
|
||||||
if (!mMainHandler.hasMessages(MainHandler.MSG_REBUILD_COMPLETE)) {
|
|
||||||
Message msg = mMainHandler.obtainMessage(
|
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
|
||||||
MainHandler.MSG_REBUILD_COMPLETE, filteredApps);
|
|
||||||
mMainHandler.sendMessage(msg);
|
if (filter != null) {
|
||||||
|
filter.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ApplicationInfo> apps;
|
||||||
|
synchronized (mEntriesMap) {
|
||||||
|
apps = new ArrayList<ApplicationInfo>(mApplications);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<AppEntry> filteredApps = new ArrayList<AppEntry>();
|
||||||
|
if (DEBUG) Log.i(TAG, "Rebuilding...");
|
||||||
|
for (int i=0; i<apps.size(); i++) {
|
||||||
|
ApplicationInfo info = apps.get(i);
|
||||||
|
if (filter == null || filter.filterApp(info)) {
|
||||||
|
synchronized (mEntriesMap) {
|
||||||
|
if (DEBUG_LOCKING) Log.v(TAG, "rebuild acquired lock");
|
||||||
|
AppEntry entry = getEntryLocked(info);
|
||||||
|
entry.ensureLabel(mContext);
|
||||||
|
if (DEBUG) Log.i(TAG, "Using " + info.packageName + ": " + entry);
|
||||||
|
filteredApps.add(entry);
|
||||||
|
if (DEBUG_LOCKING) Log.v(TAG, "rebuild releasing lock");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collections.sort(filteredApps, comparator);
|
||||||
|
|
||||||
|
synchronized (mRebuildSync) {
|
||||||
|
if (!mRebuildRequested) {
|
||||||
|
mLastAppList = filteredApps;
|
||||||
|
if (!mRebuildAsync) {
|
||||||
|
mRebuildResult = filteredApps;
|
||||||
|
mRebuildSync.notifyAll();
|
||||||
|
} else {
|
||||||
|
if (!mMainHandler.hasMessages(MainHandler.MSG_REBUILD_COMPLETE, this)) {
|
||||||
|
Message msg = mMainHandler.obtainMessage(
|
||||||
|
MainHandler.MSG_REBUILD_COMPLETE, this);
|
||||||
|
mMainHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
public void release() {
|
||||||
|
pause();
|
||||||
|
synchronized (mEntriesMap) {
|
||||||
|
mSessions.remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Session newSession(Callbacks callbacks) {
|
||||||
|
Session s = new Session(callbacks);
|
||||||
|
synchronized (mEntriesMap) {
|
||||||
|
mSessions.add(s);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doResumeIfNeededLocked() {
|
||||||
|
if (mResumed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mResumed = true;
|
||||||
|
if (mPackageIntentReceiver == null) {
|
||||||
|
mPackageIntentReceiver = new PackageIntentReceiver();
|
||||||
|
mPackageIntentReceiver.registerReceiver();
|
||||||
|
}
|
||||||
|
mApplications = mPm.getInstalledApplications(
|
||||||
|
PackageManager.GET_UNINSTALLED_PACKAGES |
|
||||||
|
PackageManager.GET_DISABLED_COMPONENTS);
|
||||||
|
if (mApplications == null) {
|
||||||
|
mApplications = new ArrayList<ApplicationInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mInterestingConfigChanges.applyNewConfig(mContext.getResources())) {
|
||||||
|
// If an interesting part of the configuration has changed, we
|
||||||
|
// should completely reload the app entries.
|
||||||
|
mEntriesMap.clear();
|
||||||
|
mAppEntries.clear();
|
||||||
|
} else {
|
||||||
|
for (int i=0; i<mAppEntries.size(); i++) {
|
||||||
|
mAppEntries.get(i).sizeStale = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<mApplications.size(); i++) {
|
||||||
|
final ApplicationInfo info = mApplications.get(i);
|
||||||
|
// Need to trim out any applications that are disabled by
|
||||||
|
// something different than the user.
|
||||||
|
if (!info.enabled && info.enabledSetting
|
||||||
|
!= PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
|
||||||
|
mApplications.remove(i);
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final AppEntry entry = mEntriesMap.get(info.packageName);
|
||||||
|
if (entry != null) {
|
||||||
|
entry.info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCurComputingSizePkg = null;
|
||||||
|
if (!mBackgroundHandler.hasMessages(BackgroundHandler.MSG_LOAD_ENTRIES)) {
|
||||||
|
mBackgroundHandler.sendEmptyMessage(BackgroundHandler.MSG_LOAD_ENTRIES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doPauseIfNeededLocked() {
|
||||||
|
if (!mResumed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i=0; i<mSessions.size(); i++) {
|
||||||
|
if (mSessions.get(i).mResumed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mResumed = false;
|
||||||
|
if (mPackageIntentReceiver != null) {
|
||||||
|
mPackageIntentReceiver.unregisterReceiver();
|
||||||
|
mPackageIntentReceiver = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppEntry getEntry(String packageName) {
|
AppEntry getEntry(String packageName) {
|
||||||
@@ -772,7 +860,18 @@ public class ApplicationsState {
|
|||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
// Always try rebuilding list first thing, if needed.
|
// Always try rebuilding list first thing, if needed.
|
||||||
handleRebuildList();
|
ArrayList<Session> rebuildingSessions = null;
|
||||||
|
synchronized (mEntriesMap) {
|
||||||
|
if (mRebuildingSessions.size() > 0) {
|
||||||
|
rebuildingSessions = new ArrayList<Session>(mRebuildingSessions);
|
||||||
|
mRebuildingSessions.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rebuildingSessions != null) {
|
||||||
|
for (int i=0; i<rebuildingSessions.size(); i++) {
|
||||||
|
rebuildingSessions.get(i).handleRebuildList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_REBUILD_LIST: {
|
case MSG_REBUILD_LIST: {
|
||||||
|
@@ -98,6 +98,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
private AppWidgetManager mAppWidgetManager;
|
private AppWidgetManager mAppWidgetManager;
|
||||||
private DevicePolicyManager mDpm;
|
private DevicePolicyManager mDpm;
|
||||||
private ApplicationsState mState;
|
private ApplicationsState mState;
|
||||||
|
private ApplicationsState.Session mSession;
|
||||||
private ApplicationsState.AppEntry mAppEntry;
|
private ApplicationsState.AppEntry mAppEntry;
|
||||||
private PackageInfo mPackageInfo;
|
private PackageInfo mPackageInfo;
|
||||||
private CanBeOnSdCardChecker mCanBeOnSdCardChecker;
|
private CanBeOnSdCardChecker mCanBeOnSdCardChecker;
|
||||||
@@ -348,6 +349,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
mState = ApplicationsState.getInstance(getActivity().getApplication());
|
mState = ApplicationsState.getInstance(getActivity().getApplication());
|
||||||
|
mSession = mState.newSession(this);
|
||||||
mPm = getActivity().getPackageManager();
|
mPm = getActivity().getPackageManager();
|
||||||
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
|
IBinder b = ServiceManager.getService(Context.USB_SERVICE);
|
||||||
mUsbManager = IUsbManager.Stub.asInterface(b);
|
mUsbManager = IUsbManager.Stub.asInterface(b);
|
||||||
@@ -423,7 +425,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
mState.resume(this);
|
mSession.resume();
|
||||||
if (!refreshUi()) {
|
if (!refreshUi()) {
|
||||||
setIntentAndFinish(true, true);
|
setIntentAndFinish(true, true);
|
||||||
}
|
}
|
||||||
@@ -432,7 +434,7 @@ public class InstalledAppDetails extends Fragment
|
|||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
mState.pause();
|
mSession.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user