• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.settings.applications;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.DialogFragment;
23 import android.app.Fragment;
24 import android.app.admin.DevicePolicyManager;
25 import android.content.BroadcastReceiver;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.content.pm.PackageInfo;
30 import android.content.pm.PackageManager;
31 import android.content.pm.PackageManager.NameNotFoundException;
32 import android.hardware.usb.IUsbManager;
33 import android.os.Bundle;
34 import android.os.IBinder;
35 import android.os.ServiceManager;
36 import android.os.UserHandle;
37 import android.os.UserManager;
38 import android.util.Log;
39 
40 import com.android.internal.logging.nano.MetricsProto;
41 import com.android.settings.SettingsActivity;
42 import com.android.settings.SettingsPreferenceFragment;
43 import com.android.settings.Utils;
44 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
45 import com.android.settings.overlay.FeatureFactory;
46 import com.android.settingslib.RestrictedLockUtils;
47 import com.android.settingslib.applications.ApplicationsState;
48 import com.android.settingslib.applications.ApplicationsState.AppEntry;
49 
50 import java.util.ArrayList;
51 
52 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
53 
54 public abstract class AppInfoBase extends SettingsPreferenceFragment
55         implements ApplicationsState.Callbacks {
56 
57     public static final String ARG_PACKAGE_NAME = "package";
58     public static final String ARG_PACKAGE_UID = "uid";
59 
60     protected static final String TAG = AppInfoBase.class.getSimpleName();
61     protected static final boolean localLOGV = false;
62 
63     protected EnforcedAdmin mAppsControlDisallowedAdmin;
64     protected boolean mAppsControlDisallowedBySystem;
65 
66     protected ApplicationFeatureProvider mApplicationFeatureProvider;
67     protected ApplicationsState mState;
68     protected ApplicationsState.Session mSession;
69     protected ApplicationsState.AppEntry mAppEntry;
70     protected PackageInfo mPackageInfo;
71     protected int mUserId;
72     protected String mPackageName;
73 
74     protected IUsbManager mUsbManager;
75     protected DevicePolicyManager mDpm;
76     protected UserManager mUserManager;
77     protected PackageManager mPm;
78 
79     // Dialog identifiers used in showDialog
80     protected static final int DLG_BASE = 0;
81 
82     protected boolean mFinishing;
83     protected boolean mListeningToPackageRemove;
84 
85     @Override
onCreate(Bundle savedInstanceState)86     public void onCreate(Bundle savedInstanceState) {
87         super.onCreate(savedInstanceState);
88         mFinishing = false;
89         final Activity activity = getActivity();
90         mApplicationFeatureProvider = FeatureFactory.getFactory(activity)
91                 .getApplicationFeatureProvider(activity);
92         mState = ApplicationsState.getInstance(activity.getApplication());
93         mSession = mState.newSession(this);
94         mDpm = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
95         mUserManager = (UserManager) activity.getSystemService(Context.USER_SERVICE);
96         mPm = activity.getPackageManager();
97         IBinder b = ServiceManager.getService(Context.USB_SERVICE);
98         mUsbManager = IUsbManager.Stub.asInterface(b);
99 
100         retrieveAppEntry();
101         startListeningToPackageRemove();
102     }
103 
104     @Override
onResume()105     public void onResume() {
106         super.onResume();
107         mSession.resume();
108         mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
109                 UserManager.DISALLOW_APPS_CONTROL, mUserId);
110         mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
111                 UserManager.DISALLOW_APPS_CONTROL, mUserId);
112 
113         if (!refreshUi()) {
114             setIntentAndFinish(true, true);
115         }
116     }
117 
118     @Override
onPause()119     public void onPause() {
120         mSession.pause();
121         super.onPause();
122     }
123 
124     @Override
onDestroy()125     public void onDestroy() {
126         stopListeningToPackageRemove();
127         mSession.release();
128         super.onDestroy();
129     }
130 
retrieveAppEntry()131     protected String retrieveAppEntry() {
132         final Bundle args = getArguments();
133         mPackageName = (args != null) ? args.getString(ARG_PACKAGE_NAME) : null;
134         if (mPackageName == null) {
135             Intent intent = (args == null) ?
136                     getActivity().getIntent() : (Intent) args.getParcelable("intent");
137             if (intent != null) {
138                 mPackageName = intent.getData().getSchemeSpecificPart();
139             }
140         }
141         mUserId = UserHandle.myUserId();
142         mAppEntry = mState.getEntry(mPackageName, mUserId);
143         if (mAppEntry != null) {
144             // Get application info again to refresh changed properties of application
145             try {
146                 mPackageInfo = mPm.getPackageInfo(mAppEntry.info.packageName,
147                         PackageManager.MATCH_DISABLED_COMPONENTS |
148                         PackageManager.MATCH_ANY_USER |
149                         PackageManager.GET_SIGNATURES |
150                         PackageManager.GET_PERMISSIONS);
151             } catch (NameNotFoundException e) {
152                 Log.e(TAG, "Exception when retrieving package:" + mAppEntry.info.packageName, e);
153             }
154         } else {
155             Log.w(TAG, "Missing AppEntry; maybe reinstalling?");
156             mPackageInfo = null;
157         }
158 
159         return mPackageName;
160     }
161 
setIntentAndFinish(boolean finish, boolean appChanged)162     protected void setIntentAndFinish(boolean finish, boolean appChanged) {
163         if (localLOGV) Log.i(TAG, "appChanged="+appChanged);
164         Intent intent = new Intent();
165         intent.putExtra(ManageApplications.APP_CHG, appChanged);
166         SettingsActivity sa = (SettingsActivity)getActivity();
167         sa.finishPreferencePanel(this, Activity.RESULT_OK, intent);
168         mFinishing = true;
169     }
170 
showDialogInner(int id, int moveErrorCode)171     protected void showDialogInner(int id, int moveErrorCode) {
172         DialogFragment newFragment = MyAlertDialogFragment.newInstance(id, moveErrorCode);
173         newFragment.setTargetFragment(this, 0);
174         newFragment.show(getFragmentManager(), "dialog " + id);
175     }
176 
refreshUi()177     protected abstract boolean refreshUi();
createDialog(int id, int errorCode)178     protected abstract AlertDialog createDialog(int id, int errorCode);
179 
180     @Override
onRunningStateChanged(boolean running)181     public void onRunningStateChanged(boolean running) {
182         // No op.
183     }
184 
185     @Override
onRebuildComplete(ArrayList<AppEntry> apps)186     public void onRebuildComplete(ArrayList<AppEntry> apps) {
187         // No op.
188     }
189 
190     @Override
onPackageIconChanged()191     public void onPackageIconChanged() {
192         // No op.
193     }
194 
195     @Override
onPackageSizeChanged(String packageName)196     public void onPackageSizeChanged(String packageName) {
197         // No op.
198     }
199 
200     @Override
onAllSizesComputed()201     public void onAllSizesComputed() {
202         // No op.
203     }
204 
205     @Override
onLauncherInfoChanged()206     public void onLauncherInfoChanged() {
207         // No op.
208     }
209 
210     @Override
onLoadEntriesCompleted()211     public void onLoadEntriesCompleted() {
212         // No op.
213     }
214 
215     @Override
onPackageListChanged()216     public void onPackageListChanged() {
217         refreshUi();
218     }
219 
startAppInfoFragment(Class<?> fragment, int titleRes, String pkg, int uid, Fragment source, int request, int sourceMetricsCategory)220     public static void startAppInfoFragment(Class<?> fragment, int titleRes,
221             String pkg, int uid, Fragment source, int request, int sourceMetricsCategory) {
222         startAppInfoFragment(fragment, titleRes, pkg, uid, source.getActivity(), request,
223                 sourceMetricsCategory);
224     }
225 
startAppInfoFragment(Class<?> fragment, int titleRes, String pkg, int uid, Activity source, int request, int sourceMetricsCategory)226     public static void startAppInfoFragment(Class<?> fragment, int titleRes,
227             String pkg, int uid, Activity source, int request, int sourceMetricsCategory) {
228         Bundle args = new Bundle();
229         args.putString(AppInfoBase.ARG_PACKAGE_NAME, pkg);
230         args.putInt(AppInfoBase.ARG_PACKAGE_UID, uid);
231 
232         Intent intent = Utils.onBuildStartFragmentIntent(source, fragment.getName(),
233                 args, null, titleRes, null, false, sourceMetricsCategory);
234         source.startActivityForResultAsUser(intent, request,
235                 new UserHandle(UserHandle.getUserId(uid)));
236     }
237 
238     public static class MyAlertDialogFragment extends InstrumentedDialogFragment {
239 
240         private static final String ARG_ID = "id";
241 
242         @Override
getMetricsCategory()243         public int getMetricsCategory() {
244             return MetricsProto.MetricsEvent.DIALOG_APP_INFO_ACTION;
245         }
246 
247         @Override
onCreateDialog(Bundle savedInstanceState)248         public Dialog onCreateDialog(Bundle savedInstanceState) {
249             int id = getArguments().getInt(ARG_ID);
250             int errorCode = getArguments().getInt("moveError");
251             Dialog dialog = ((AppInfoBase) getTargetFragment()).createDialog(id, errorCode);
252             if (dialog == null) {
253                 throw new IllegalArgumentException("unknown id " + id);
254             }
255             return dialog;
256         }
257 
newInstance(int id, int errorCode)258         public static MyAlertDialogFragment newInstance(int id, int errorCode) {
259             MyAlertDialogFragment dialogFragment = new MyAlertDialogFragment();
260             Bundle args = new Bundle();
261             args.putInt(ARG_ID, id);
262             args.putInt("moveError", errorCode);
263             dialogFragment.setArguments(args);
264             return dialogFragment;
265         }
266     }
267 
startListeningToPackageRemove()268     protected void startListeningToPackageRemove() {
269         if (mListeningToPackageRemove) {
270             return;
271         }
272         mListeningToPackageRemove = true;
273         final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
274         filter.addDataScheme("package");
275         getContext().registerReceiver(mPackageRemovedReceiver, filter);
276     }
277 
stopListeningToPackageRemove()278     protected void stopListeningToPackageRemove() {
279         if (!mListeningToPackageRemove) {
280             return;
281         }
282         mListeningToPackageRemove = false;
283         getContext().unregisterReceiver(mPackageRemovedReceiver);
284     }
285 
onPackageRemoved()286     protected void onPackageRemoved() {
287         getActivity().finishAndRemoveTask();
288     }
289 
290     protected final BroadcastReceiver mPackageRemovedReceiver = new BroadcastReceiver() {
291         @Override
292         public void onReceive(Context context, Intent intent) {
293             String packageName = intent.getData().getSchemeSpecificPart();
294             if (!mFinishing && mAppEntry.info.packageName.equals(packageName)) {
295                 onPackageRemoved();
296             }
297         }
298     };
299 
300 }
301