From 247df4fe798d63ab99fed6fd7c4de0fc913b3aec Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Tue, 17 Jan 2012 09:36:47 -0800 Subject: Add AppNavigation demo This demo illustrates the use of the new support library functionality for navigating within and across tasks using "up" navigation. This matches the recommendations in the Android design guide. Change-Id: I2b36c962dd24f0e0f3b3ee3f86319dafc2fc66e2 --- .../android/appnavigation/app/ActionBarCompat.java | 42 +++++++ .../appnavigation/app/AppNavHomeActivity.java | 121 +++++++++++++++++++++ .../appnavigation/app/ContentCategoryActivity.java | 50 +++++++++ .../appnavigation/app/ContentViewActivity.java | 67 ++++++++++++ .../app/InterstitialMessageActivity.java | 42 +++++++ .../appnavigation/app/NotificationsActivity.java | 80 ++++++++++++++ .../appnavigation/app/OutsideTaskActivity.java | 38 +++++++ .../android/appnavigation/app/PeerActivity.java | 62 +++++++++++ .../appnavigation/app/SimpleUpActivity.java | 44 ++++++++ .../app/ViewFromOtherTaskActivity.java | 52 +++++++++ 10 files changed, 598 insertions(+) create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/ActionBarCompat.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/AppNavHomeActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/ContentCategoryActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/ContentViewActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/InterstitialMessageActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/NotificationsActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/OutsideTaskActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/PeerActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/SimpleUpActivity.java create mode 100644 samples/AppNavigation/src/com/example/android/appnavigation/app/ViewFromOtherTaskActivity.java (limited to 'samples/AppNavigation/src/com/example') diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/ActionBarCompat.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/ActionBarCompat.java new file mode 100644 index 000000000..08223366f --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/ActionBarCompat.java @@ -0,0 +1,42 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import android.app.Activity; +import android.os.Build; + +/** + * Very limited shim for enabling the action bar's up button on devices that support it. + */ +public class ActionBarCompat { + /** + * This class will only ever be loaded if the version check succeeds, + * keeping the verifier from rejecting the use of framework classes that + * don't exist on older platform versions. + */ + static class ActionBarCompatImpl { + static void setDisplayHomeAsUpEnabled(Activity activity, boolean enable) { + activity.getActionBar().setDisplayHomeAsUpEnabled(enable); + } + } + + public static void setDisplayHomeAsUpEnabled(Activity activity, boolean enable) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + ActionBarCompatImpl.setDisplayHomeAsUpEnabled(activity, enable); + } + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/AppNavHomeActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/AppNavHomeActivity.java new file mode 100644 index 000000000..469ab4e98 --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/AppNavHomeActivity.java @@ -0,0 +1,121 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import android.app.ListActivity; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ListView; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.List; + +/** + * Home activity for app navigation code samples. + */ +public class AppNavHomeActivity extends ListActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setListAdapter(new SampleAdapter(querySampleActivities())); + } + + @Override + protected void onListItemClick(ListView lv, View v, int pos, long id) { + SampleInfo info = (SampleInfo) getListAdapter().getItem(pos); + startActivity(info.intent); + } + + protected List querySampleActivities() { + Intent intent = new Intent(Intent.ACTION_MAIN, null); + intent.setPackage(getPackageName()); + intent.addCategory(Intent.CATEGORY_SAMPLE_CODE); + + PackageManager pm = getPackageManager(); + List infos = pm.queryIntentActivities(intent, 0); + + ArrayList samples = new ArrayList(); + + final int count = infos.size(); + for (int i = 0; i < count; i++) { + final ResolveInfo info = infos.get(i); + final CharSequence labelSeq = info.loadLabel(pm); + String label = labelSeq != null ? labelSeq.toString() : info.activityInfo.name; + + Intent target = new Intent(); + target.setClassName(info.activityInfo.applicationInfo.packageName, + info.activityInfo.name); + SampleInfo sample = new SampleInfo(label, target); + samples.add(sample); + } + + return samples; + } + + static class SampleInfo { + String name; + Intent intent; + + SampleInfo(String name, Intent intent) { + this.name = name; + this.intent = intent; + } + } + + class SampleAdapter extends BaseAdapter { + private List mItems; + + public SampleAdapter(List items) { + mItems = items; + } + + @Override + public int getCount() { + return mItems.size(); + } + + @Override + public Object getItem(int position) { + return mItems.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, + parent, false); + convertView.setTag(convertView.findViewById(android.R.id.text1)); + } + TextView tv = (TextView) convertView.getTag(); + tv.setText(mItems.get(position).name); + return convertView; + } + + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/ContentCategoryActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/ContentCategoryActivity.java new file mode 100644 index 000000000..534f391d2 --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/ContentCategoryActivity.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.view.MenuItem; +import android.view.View; + +public class ContentCategoryActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.content_category); + + ActionBarCompat.setDisplayHomeAsUpEnabled(this, true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } + + public void onViewContent(View v) { + Intent target = new Intent(this, ContentViewActivity.class); + startActivity(target); + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/ContentViewActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/ContentViewActivity.java new file mode 100644 index 000000000..528323092 --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/ContentViewActivity.java @@ -0,0 +1,67 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.support.v4.app.ShareCompat; +import android.support.v4.app.TaskStackBuilder; +import android.text.TextUtils; +import android.view.MenuItem; +import android.widget.TextView; + +public class ContentViewActivity extends Activity { + public static final String EXTRA_TEXT = "com.example.android.appnavigation.EXTRA_TEXT"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.content_view); + + ActionBarCompat.setDisplayHomeAsUpEnabled(this, true); + + Intent intent = getIntent(); + if (Intent.ACTION_VIEW.equals(intent.getAction())) { + TextView tv = (TextView) findViewById(R.id.status_text); + tv.setText("Viewing content from ACTION_VIEW"); + } else if (intent.hasExtra(EXTRA_TEXT)) { + TextView tv = (TextView) findViewById(R.id.status_text); + tv.setText(intent.getStringExtra(EXTRA_TEXT)); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + Intent upIntent = NavUtils.getParentActivityIntent(this); + if (NavUtils.shouldUpRecreateTask(this, upIntent)) { + TaskStackBuilder.from(this) + .addParentStack(this) + .startActivities(); + finish(); + } else { + NavUtils.navigateUpTo(this, upIntent); + } + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/InterstitialMessageActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/InterstitialMessageActivity.java new file mode 100644 index 000000000..1d0154d3d --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/InterstitialMessageActivity.java @@ -0,0 +1,42 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.TaskStackBuilder; +import android.view.View; + +public class InterstitialMessageActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.interstitial_message); + } + + public void onViewContent(View v) { + TaskStackBuilder.from(this) + .addParentStack(ContentViewActivity.class) + .addNextIntent(new Intent(this, ContentViewActivity.class) + .putExtra(ContentViewActivity.EXTRA_TEXT, "From Interstitial Notification")) + .startActivities(); + finish(); + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/NotificationsActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/NotificationsActivity.java new file mode 100644 index 000000000..f14dbc682 --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/NotificationsActivity.java @@ -0,0 +1,80 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.Activity; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.TaskStackBuilder; +import android.view.MenuItem; +import android.view.View; + +public class NotificationsActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.notifications); + + ActionBarCompat.setDisplayHomeAsUpEnabled(this, true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } + + public void onPostDirect(View v) { + NotificationCompat.Builder builder = new NotificationCompat.Builder(this) + .setTicker("Direct Notification") + .setSmallIcon(android.R.drawable.stat_notify_chat) + .setContentTitle("Direct Notification") + .setContentText("This will open the content viewer") + .setAutoCancel(true) + .setContentIntent(TaskStackBuilder.from(this) + .addParentStack(ContentViewActivity.class) + .addNextIntent(new Intent(this, ContentViewActivity.class) + .putExtra(ContentViewActivity.EXTRA_TEXT, "From Notification")) + .getPendingIntent(0, 0)); + NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + nm.notify("direct_tag", R.id.direct_notification, builder.getNotification()); + } + + public void onPostInterstitial(View v) { + NotificationCompat.Builder builder = new NotificationCompat.Builder(this) + .setTicker("Interstitial Notification") + .setSmallIcon(android.R.drawable.stat_notify_chat) + .setContentTitle("Interstitial Notification") + .setContentText("This will show a detail page") + .setAutoCancel(true) + .setContentIntent(PendingIntent.getActivity(this, 0, + new Intent(this, InterstitialMessageActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_CLEAR_TASK), 0)); + NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + nm.notify("interstitial_tag", R.id.interstitial_notification, builder.getNotification()); + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/OutsideTaskActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/OutsideTaskActivity.java new file mode 100644 index 000000000..4022fa61d --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/OutsideTaskActivity.java @@ -0,0 +1,38 @@ +/* + * 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. + */ +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +public class OutsideTaskActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.outside_task); + } + + public void onViewContent(View v) { + Intent intent = new Intent(Intent.ACTION_VIEW) + .setType("application/x-example") + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); + startActivity(intent); + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/PeerActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/PeerActivity.java new file mode 100644 index 000000000..45083fdc1 --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/PeerActivity.java @@ -0,0 +1,62 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.ActionBar; +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; + +public class PeerActivity extends Activity { + private static final String EXTRA_PEER_COUNT = + "com.example.android.appnavigation.EXTRA_PEER_COUNT"; + + private int mPeerCount; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.peer); + + ActionBarCompat.setDisplayHomeAsUpEnabled(this, true); + + mPeerCount = getIntent().getIntExtra(EXTRA_PEER_COUNT, 0) + 1; + TextView tv = (TextView) findViewById(R.id.peer_counter); + tv.setText(getResources().getText(R.string.peer_count).toString() + mPeerCount); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } + + public void onLaunchPeer(View v) { + Intent target = new Intent(this, PeerActivity.class); + target.putExtra(EXTRA_PEER_COUNT, mPeerCount); + startActivity(target); + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/SimpleUpActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/SimpleUpActivity.java new file mode 100644 index 000000000..4141951e2 --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/SimpleUpActivity.java @@ -0,0 +1,44 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.ActionBar; +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.view.MenuItem; + +public class SimpleUpActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.simple_up); + + ActionBarCompat.setDisplayHomeAsUpEnabled(this, true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + NavUtils.navigateUpFromSameTask(this); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/samples/AppNavigation/src/com/example/android/appnavigation/app/ViewFromOtherTaskActivity.java b/samples/AppNavigation/src/com/example/android/appnavigation/app/ViewFromOtherTaskActivity.java new file mode 100644 index 000000000..06e1699cd --- /dev/null +++ b/samples/AppNavigation/src/com/example/android/appnavigation/app/ViewFromOtherTaskActivity.java @@ -0,0 +1,52 @@ +/* + * 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. + */ + +package com.example.android.appnavigation.app; + +import com.example.android.appnavigation.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.view.MenuItem; +import android.view.View; + +public class ViewFromOtherTaskActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.view_from_other_task); + + ActionBarCompat.setDisplayHomeAsUpEnabled(this, true); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + NavUtils.navigateUpFromSameTask(this); + return true; + } + return false; + } + + public void onLaunchOtherTask(View v) { + Intent target = new Intent(this, OutsideTaskActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_TASK_ON_HOME); + startActivity(target); + } +} -- cgit v1.2.3