1/*
2 * Copyright (C) 2007 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
17package com.android.development;
18
19import android.app.Activity;
20import android.app.ActivityManager;
21import android.content.ComponentName;
22import android.content.Context;
23import android.content.Intent;
24import android.content.pm.ActivityInfo;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.InstrumentationInfo;
27import android.content.pm.PackageInfo;
28import android.content.pm.PackageManager;
29import android.content.pm.ProviderInfo;
30import android.content.pm.ServiceInfo;
31import android.net.Uri;
32import android.os.Bundle;
33import android.util.Log;
34import android.view.LayoutInflater;
35import android.view.View;
36import android.widget.Button;
37import android.widget.ImageView;
38import android.widget.LinearLayout;
39import android.widget.TextView;
40
41public class PackageSummary extends Activity {
42
43    String mPackageName;
44    private TextView mPackage;
45    private ImageView mIconImage;
46    private TextView mClass;
47    private TextView mLabel;
48    private View mDisabled;
49    private View mSystem;
50    private View mDebuggable;
51    private View mNoCode;
52    private View mPersistent;
53    private Button mRestart;
54    private TextView mTask;
55    private TextView mVersion;
56    private TextView mProcess;
57    private TextView mUid;
58    private TextView mSource;
59    private TextView mData;
60
61    @Override
62    protected void onCreate(Bundle icicle) {
63        super.onCreate(icicle);
64
65        setContentView(R.layout.package_summary);
66
67        final PackageManager pm = getPackageManager();
68
69        mPackage = (TextView)findViewById(R.id.packageView);
70        mIconImage = (ImageView)findViewById(R.id.icon);
71        mClass = (TextView)findViewById(R.id.classView);
72        mLabel = (TextView)findViewById(R.id.label);
73        mDisabled = findViewById(R.id.disabled);
74        mSystem = findViewById(R.id.system);
75        mDebuggable = findViewById(R.id.debuggable);
76        mNoCode = findViewById(R.id.nocode);
77        mPersistent = findViewById(R.id.persistent);
78        mRestart = (Button)findViewById(R.id.restart);
79        mTask = (TextView)findViewById(R.id.task);
80        mVersion = (TextView)findViewById(R.id.version);
81        mUid = (TextView)findViewById(R.id.uid);
82        mProcess = (TextView)findViewById(R.id.process);
83        mSource = (TextView)findViewById(R.id.source);
84        mData = (TextView)findViewById(R.id.data);
85
86        mPackageName = getIntent().getData().getSchemeSpecificPart();
87        PackageInfo info = null;
88        try {
89            info = pm.getPackageInfo(mPackageName,
90                PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
91                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS
92                | PackageManager.GET_INSTRUMENTATION
93                | PackageManager.GET_DISABLED_COMPONENTS);
94        } catch (PackageManager.NameNotFoundException e) {
95        }
96
97        if (info != null) {
98            mPackage.setText(info.packageName);
99            CharSequence label = null;
100            String appClass = null;
101            if (info.applicationInfo != null) {
102                mIconImage.setImageDrawable(
103                    pm.getApplicationIcon(info.applicationInfo));
104                label = info.applicationInfo.nonLocalizedLabel;
105                appClass = info.applicationInfo.className;
106                if (info.applicationInfo.enabled) {
107                    mDisabled.setVisibility(View.GONE);
108                }
109                if ((info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
110                    mSystem.setVisibility(View.GONE);
111                }
112                if ((info.applicationInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
113                    mDebuggable.setVisibility(View.GONE);
114                }
115                if ((info.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
116                    mNoCode.setVisibility(View.GONE);
117                }
118                if ((info.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
119                    mPersistent.setVisibility(View.GONE);
120                }
121                mUid.setText(Integer.toString(info.applicationInfo.uid));
122                mProcess.setText(info.applicationInfo.processName);
123                if (info.versionName != null) {
124                    mVersion.setText(info.versionName + " (#" + info.versionCode + ")");
125                } else {
126                    mVersion.setText("(#" + info.versionCode + ")");
127                }
128                mSource.setText(info.applicationInfo.sourceDir);
129                mData.setText(info.applicationInfo.dataDir);
130                if (info.applicationInfo.taskAffinity != null) {
131                    mTask.setText("\"" + info.applicationInfo.taskAffinity + "\"");
132                } else {
133                    mTask.setText("(No Task Affinity)");
134                }
135            }
136            if (appClass != null) {
137                if (appClass.startsWith(info.packageName + "."))
138                    mClass.setText(appClass.substring(info.packageName.length()));
139                else
140                    mClass.setText(appClass);
141            } else {
142                mClass.setText("(No Application Class)");
143            }
144            if (label != null) {
145                mLabel.setText("\"" + label + "\"");
146            } else {
147                mLabel.setText("(No Label)");
148            }
149
150            mRestart.setOnClickListener(new View.OnClickListener() {
151                public void onClick(View v) {
152                    ActivityManager am = (ActivityManager)getSystemService(
153                            Context.ACTIVITY_SERVICE);
154                    am.killBackgroundProcesses(mPackageName);
155                }
156            });
157
158            final LayoutInflater inflate =
159                (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
160            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
161                LinearLayout.LayoutParams.WRAP_CONTENT,
162                LinearLayout.LayoutParams.WRAP_CONTENT);
163            LinearLayout activities = (LinearLayout)findViewById(R.id.activities);
164            LinearLayout receivers = (LinearLayout)findViewById(R.id.receivers);
165            LinearLayout services = (LinearLayout)findViewById(R.id.services);
166            LinearLayout providers = (LinearLayout)findViewById(R.id.providers);
167            LinearLayout instrumentation = (LinearLayout)findViewById(R.id.instrumentation);
168
169            if (info.activities != null) {
170                final int N = info.activities.length;
171                for (int i=0; i<N; i++) {
172                    ActivityInfo ai = info.activities[i];
173                    // If an activity is disabled then the ActivityInfo will be null
174                    if (ai != null) {
175                        Button view = (Button)inflate.inflate(
176                                R.layout.package_item, null, false);
177                        view.setOnClickListener(new ActivityOnClick(
178                                new ComponentName(ai.applicationInfo.packageName,
179                                                  ai.name)));
180                        setItemText(view, info, ai.name);
181                        activities.addView(view, lp);
182                    }
183                }
184            } else {
185                activities.setVisibility(View.GONE);
186            }
187
188            if (info.receivers != null) {
189                final int N = info.receivers.length;
190                for (int i=0; i<N; i++) {
191                    ActivityInfo ai = info.receivers[i];
192                    Button view = (Button)inflate.inflate(
193                        R.layout.package_item, null, false);
194                    Log.i("foo", "Receiver #" + i + " of " + N + ": " + ai);
195                    setItemText(view, info, ai.name);
196                    receivers.addView(view, lp);
197                }
198            } else {
199                receivers.setVisibility(View.GONE);
200            }
201
202            if (info.services != null) {
203                final int N = info.services.length;
204                for (int i=0; i<N; i++) {
205                    ServiceInfo si = info.services[i];
206                    Button view = (Button)inflate.inflate(
207                        R.layout.package_item, null, false);
208                    setItemText(view, info, si.name);
209                    services.addView(view, lp);
210                }
211            } else {
212                services.setVisibility(View.GONE);
213            }
214
215            if (info.providers != null) {
216                final int N = info.providers.length;
217                for (int i=0; i<N; i++) {
218                    ProviderInfo pi = info.providers[i];
219                    Button view = (Button)inflate.inflate(
220                        R.layout.package_item, null, false);
221                    setItemText(view, info, pi.name);
222                    providers.addView(view, lp);
223                }
224            } else {
225                providers.setVisibility(View.GONE);
226            }
227
228            if (info.instrumentation != null) {
229                final int N = info.instrumentation.length;
230                for (int i=0; i<N; i++) {
231                    InstrumentationInfo ii = info.instrumentation[i];
232                    Button view = (Button)inflate.inflate(
233                        R.layout.package_item, null, false);
234                    setItemText(view, info, ii.name);
235                    instrumentation.addView(view, lp);
236                }
237            } else {
238                instrumentation.setVisibility(View.GONE);
239            }
240
241        }
242
243        // Put focus here, so a button doesn't get focus and cause the
244        // scroll view to move to it.
245        mPackage.requestFocus();
246    }
247
248    private final static void setItemText(Button item, PackageInfo pi,
249                                          String className)
250    {
251        item.setText(className.substring(className.lastIndexOf('.')+1));
252    }
253
254    private final class ActivityOnClick implements View.OnClickListener
255    {
256        private final ComponentName mClassName;
257        ActivityOnClick(ComponentName className) {
258            mClassName = className;
259        }
260
261        public void onClick(View v) {
262            Intent intent = new Intent(
263                null, Uri.fromParts("component",
264                    mClassName.flattenToString(), null));
265            intent.setClass(PackageSummary.this, ShowActivity.class);
266            startActivity(intent);
267        }
268    }
269}
270