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